一、需求
用nuxt2搭的官网项目,在网页点击查看源码,搜索不到顶部服务站群各站点的a标签信息,不利于seo。经排查,获取服务站群的接口是在mounted阶段调用的,现需在服务器渲染阶段调用
二、思考
头部组件是放在全局组件components里的,在layouts里的default.vue默认布局中使用
<template>
<div>
<app-header />
<nuxt />
<app-footer />
</div>
</template>
现思考如何在服务端渲染阶段获取站点信息,并在app-header里显示
1、asyncData
在服务端调用,首先考虑到的就是asyncData,但这限于页面组件使用,layouts布局组件跟页面组件类似,是否支持,进行一波测试。
在default中写入asyncData做打印,打印未执行,说明layouts中不支持使用
2、fetch
fetch能在服务器阶段调用,将数据填充到store中。测试在app-header和defualt中是否支持,只要支持,便可从store中获取数据填充。同样做输出打印,经测试,全局组件和布局组件同样不支持fetch钩子
3、middleware
在default中设置中间件, 在此中间件中调用接口,将数据存储在store中,app-header使用store中的数据
在middlewire中建setGroupSite.js
export default async function ({ store, $axois }){
if(!store.state.siteGroup){
const { data } = await $axios.post(api)
store.commmit('siteGroup', data)
}
}
default.vue
<template>
<div>
<app-header />
<nuxt />
<app-footer />
</div>
</template>
<script>
export default{
middleware: 'setSiteGroup'
</script>
app-header
computed:{
siteGroup(){
return this.$store.state.siteGroup
}
}
自测,搜索源码,可以找到各站点的信息,此方案可行
4、nuxtServerInit
查看文档发现vuex这部分有nuxtServerInit方法,可将服务端的数据传给客户端,正好满足需求
在vuex中添加
export default function ({ store, $axois }){
if(!store.state.siteGroup){
}
}
actions: {
async nuxtServerInit ({ commit }, { req }) {
try {
const { data } = await $axios.post(api)
store.commmit('siteGroup', data)
} catch(err) {
console.log(error)
}
}
}
经测试,同样满足需求
三、middleware和nuxtServerInit的选择
1、middleware
middleware(中间件)是一个可以在页面或布局的渲染之前运行的函数,可以是全局的,也可以是特定页面的。全局中间件会在每个路由变更之前执行,而页面中间件只会在特定页面加载之前执行。这些中间件可以执行以下任务:
- 验证用户是否已经登录(身份验证)
- 设置页面的元数据
- 重定向到特定路由
- 记录或分析数据等
2、nuxtServerInit
nuxtServerInit是一个特殊的action,在Nuxt应用启动时,如果是服务器端渲染模式,该action会作为store的初始化方法被调用。这个action的主要目的是允许你在服务器端渲染期间向store中填充一些初始状态数据,仅在服务端执行一次,在客户端上不会被调用,通常用于设置初始状态例如:
- 从API获取应用的全局设置
- 在服务端对用户进行身份验证,并初始化用户状态
- 初始化应用需要的配置数据
3、选择
尽管二者都可满足需求,根据设计初衷和其职责,如果需要在路由跳转时执行一些逻辑,比如权限校验或者页面跳转,你应当使用middleware。如果需要在应用启动时仅在服务端执行一次以初始化某些数据,应当使用
nuxtServerInit。
四、nuxt3
在nuxt3中无需考虑这个问题,只要在服务器渲染的生命周期中调用,就会在页面水合时可以从服务器传递给客户端,而无需在客户端重新获取数据。
五、小结
随着前端框架和技术的丰富多样性发展,要求从业者需要掌握这些开发技能。但不容忽视的是,无论大牛还是小白,只要一段时间不用就容易忘,尤其是框架特定api的使用,所以经常查阅文档还是非常重要的。