使用nuxt进行官网开发的小结

3,076 阅读3分钟

前段时间公司要开发官网,而公司这边一直是用vue开发,所以很自然就想着用vue的服务器端渲染的方案;如果用vue-server-render插件然后自己搭建node服务,这听起来就有很多事情,不过放心,nuxt框架就是已经帮你做了这些事情,也帮我们踩了很多坑,所以就直接采用nuxt来开发服务器端渲染;

本次小结主要是记录当时开发工程中很纠结的两个方面:

1、nuxt的渲染过程;

2、数据应该在哪获取?

nuxt的渲染过程

服务器端渲染,本质上就是在服务器端上就拿到要展示的数据,然后生成好对应的html返回给web,这样很便于做seo;

渲染的流程图如下:

上面的流程,每个具体的用法可以参考nuxt文档,我想强调的是:

1)nuxtServerInit,这个是在store/index.js中定义的,nuxt会在服务器渲染的时候第一个调用,所以可以把用户信息这类全局的不经常变的信息在这里获取;

export const actions = {  
    async nuxtServerInit ({ commit }, { req }) {    
        let {data} = await getUserInfo()    commit('setUserInfo', data)  
    },
}

2)nuxt中组件可分为页面组件(pages目录下的组件)和非页面组件(components下的各个组件);

asyncData,这个方法的返回值会赋值给data中的对应属性;仅限于页面组件

async asyncData(context){
    let {id} = context.params
    let prdList = await getPrdList(id)
    return {prdList}
}

fetch,这个方法可以操作store,可以用来提前设置好vuex中的状态;

fetch ({ store, params }) {
    store.commit('setCurrentPage', Pages.About)
}

3)nuxt中组件的生命周期,

在服务器端渲染的时候,只有beforeCreate和created才会被调用;(很明显mounted那些在服务器端也没必须要调用)

在web端渲染的时候,生命周期是正常的;

现在,我们需要梳理下关心的两件事情:

1)第一次打开网页时,是怎么渲染的?

对应流程图中IncomingRequest开始的从上到下的流程;

在服务器端渲染的时候,会调用页面组件的asyncData/beforeCreate/created/fetch,以及非页面组件的beforeCreate/created/fetch,渲染完成后,传递给web;

page, asyncData
page, beforeCreate
page, created
page, fetch
component, beforeCreate
component, created
component, fetch

在web端会进行渲染,会调用组件的正常的生命周期:

page, beforeCreate
page, created
page, beforeMount
component, beforeCreate
component, created
component, beforeMount
component, mounted
page, mounted

2)web端渲染后,在网页上点击跳转又是怎么渲染的?

对应流程图中Navigate开始的流程;注意这是在web端渲染的,这时会调用页面组件的asyncData/beforeCreate/created/beforeMount/fetch/mounted,以及非页面组件的beforeCreate/created/beforeMount/fetch/mounted

page, asyncData
page, beforeCreate
page, created
page, beforeMount
page, fetch
component, beforeCreate
component, created
component, beforeMount
component, fetch
component, mounted
page, mounted

数据应该在哪获取?

我们一般会在created中获取数据,而在nuxt中,对于服务器端渲染的情况这会有两个问题:

1)created会被调用两次,导致获取两次数据;

2)更严重的问题是,nuxt并不会等created中的数据返回后才将渲染结果返回给web,导致虽然去获取数据了,但提交给web的依然是未更新的值,ssr也就没起作用;

很明显,我们就应该在asyncData中获取数据,因为nuxt会等待asyncData中的数据返回并融入到data属性中;

如果数据都在asyncData中获取,而这个方法只能在页面组件中使用,那非页面组件中要获取数据怎么办?

当然是正常获取咯,因为我们在created中获取都是初始数据,这个我们可以在页面组件中通过asyncData方法获取到后传入到非页面组件中;页面已经打开后的数据获取,我们正常调用方法获取就行;

参考

1、vue服务器端渲染的官方指南;

2、nuxt指南