vue ssr及需要掌握的点
讲些别人没有讲到的,前提是看完了官方的教程,另外,一篇文章肯定是讲不完的,此处将持续更新。
vue ssr本身之外涉及的点
- express搭建服务器
- nginx请求转发
- linux下nginx安装与配置
- lru-cache做接口与页面缓存
- 日志管理
- 结合github做项目自动化部署
图解在下面
- pm2 node进程管理
- nodemon node本地调试
- linux 服务器环境部署
- linux命令大全
- linux安装zsh与oh-my-zsh
- 安装node及npm,本身自带yum
- 服务器 支持node就bat的云,我选了最便宜的百度云第一个月9.9。顺便了解一下ECS,VPS,虚拟主机的区别。
vue ssr整体原理
在前后端分离的背景下,ssr(服务端渲染)就是做类似php和java模版引擎做的事情
so,用node做服务器,在访问vue 客户端路由的时候,匹配出涉及到的组件,即getMatchedComponents
,检查这些组件是否需要服务端的数据渲染,即组件内置method asyncData
。在所有涉及到的接口都返回后,将数据以context
传递给html拼接,window.__INITIAL_STATE__
,这就是server 端所做的事情。
到了客户端挂载的时候,需要将服务端之前取过的数据,即window.__INITIAL_STATE__
状态对接,即官方的混合,其次,如果客户端存在需要预取数据的组件,还要从这些组件中筛选出当前没有被服务端渲染过的,再去请求拿数据存到store里。
以上都是构建之外的代码逻辑,还有很重要的一点就是构建。
服务端的打包,就是将客户端中需要在服务端渲染的代码映射成一个json文件,即server-bundle.json
,通过bundleRenderer
去渲染从接口获取的数据,并拼接需要引用哪些模块的js文件即clientManifest
里标注的,然后根据给定的模版拼接好返回给express
响应请求,最后去执行客户端打包生成的文件,client-bundle
,执行客户端的逻辑。
源码结构:
shell
src
├── components
│ ├── Foo.vue
│ ├── Bar.vue
│ └── Baz.vue
├── App.vue
├── app.js # 通用 entry(universal entry)
├── entry-client.js # 仅运行于浏览器
└── entry-server.js # 仅运行于服务器
vue ssr路由与数据(router与store)的混合
router与store同app.js
里创建vue实例原理一样,需要创建一个工厂函数来返回新的实例
因为运行在服务端的代码是保存在内存中的,有且仅有一份,这么做是为了使不同的客户端得到不同的实例。
路由
路由对应的组件应该是按需加载的,和在客户端创建vue实例一样
js
export function createRouter() {
return new Router({
// 只能使用history,因为hash的变化express检测不到
mode: 'history',
routes: [
{
path: '/:id',
component: r => require.ensure([], () => r(require('../views/Index.vue')), 'Index')
}
]
})
}
不同的是,由于组件是异步的,需要等到所有组件加载完成之后才能创建实例并开始走流程。
在访问一个地址后,会push到router中,利用vuex-router-sync
,将router与同步到store中,以便保存这个“数据快照”即window.__INITIAL_STATE__
。
数据
在路由加载完成后,会根据当前路由匹配出需要渲染的组件去取数据,此时会调用组件构造函数上的一个方法(非实例)即官方的asyncData
(可随意命名),将当前store
和router
作为参数传递给它
js
asyncData({ store, route }) {
return store.dispatch('fetchItem', route.params.id)
},
这样它就可以获取数据并保存在store中。
最重要的混合步骤是在client-entry中初始化时做的
js
// entry-client.js
const { app, router, store } = createApp()
if (window.__INITIAL_STATE__) {
store.replaceState(window.__INITIAL_STATE__)
}
【参考】
自动化部署流程图
【参考】