服务端渲染的本质是后端根据路由的情况在后端渲染这个组件的html代码,然后发送到前端,前端通过传来的 data-server-rendered=”true”标识符来得知这个html是由服务器渲染的,然后进行加载到自身进行管理。
在服务端渲染的时候,beforeCreate和created生命周期都是存在于服务端的,没有任何浏览器对象,如果在里面访问document或者window这种对象会在渲染的时候node抛出异常,其他周期则运行在客户端中。
这里使用vue的脚手架来初始化项目
通过 vue-cli 脚手架生成一个基础结构
vue init webpack ssrdemo
cnpm i
安装ssr需要的插件
cnpm i webpack-node-externals vue-server-renderer -D
- webpack-node-externals:忽略打包工具,内联忽略node_modules文件件,可以为其指定白名单 whitelist让某类文件打包到包中
- vue-server-renderer 为文件生成对应json的ssr插件
安装node服务器,官方示例中使用的是express 这里使用的是koa
cnpm i koa2 koa-router koa-static koa-bodyparser --save
因为服务器渲染需要针对客户端和服务器端分别打包,所以需要两个入口文件,并把入口main.js改造成一个工厂函数,如果包含vuex或者vue-router还需要对这个两个进行改变成工厂函数并通过改造后的main函数引用,之后进行同步
在src下新建 client.js server.js 两个入口js
改造router.js,因为在服务端每一次独立请求都应该返回一个全新的router对象,所以需要这个工厂函数,vuex也是一样
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld.vue'
export function createRouter(){
return new Router({
mode:'history',
routes:[
{
path:"/",
component:HelloWorld
}
]
})
}
改造main.js
import Vue from 'vue'
import {createRouter} from '@/router/router.js'
//引入Router的工厂函数
import App from '@/App.vue'
export function createApp(){
const router=createRouter()
//生产router,如果需要vuex一样
const app = new Vue{
render:h=>h(App),
router:router
}
return {app,router}
//返回app和router
}
编写server.js