Nuxt全局组件数据在服务端渲染

538 阅读3分钟

一、需求

用nuxt2搭的官网项目,在网页点击查看源码,搜索不到顶部服务站群各站点的a标签信息,不利于seo。经排查,获取服务站群的接口是在mounted阶段调用的,现需在服务器渲染阶段调用

二、思考

头部组件是放在全局组件components里的,在layouts里的default.vue默认布局中使用

<template>
    <div>
        <app-header />
        <nuxt />
        <app-footer /> 
    </div>  
</template>

现思考如何在服务端渲染阶段获取站点信息,并在app-header里显示

1、asyncData

image.png

在服务端调用,首先考虑到的就是asyncData,但这限于页面组件使用,layouts布局组件跟页面组件类似,是否支持,进行一波测试。

在default中写入asyncData做打印,打印未执行,说明layouts中不支持使用

2、fetch

image.png

fetch能在服务器阶段调用,将数据填充到store中。测试在app-header和defualt中是否支持,只要支持,便可从store中获取数据填充。同样做输出打印,经测试,全局组件和布局组件同样不支持fetch钩子

3、middleware

image.png

在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

image.png

查看文档发现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

image.png

在nuxt3中无需考虑这个问题,只要在服务器渲染的生命周期中调用,就会在页面水合时可以从服务器传递给客户端,而无需在客户端重新获取数据。

五、小结

随着前端框架和技术的丰富多样性发展,要求从业者需要掌握这些开发技能。但不容忽视的是,无论大牛还是小白,只要一段时间不用就容易忘,尤其是框架特定api的使用,所以经常查阅文档还是非常重要的。