}
router.get('/home',handleRequest)
module.exports = router
vue-server-render 提供一个名为 createBundleRenderer 的 API 使用方法如下
const { createBundleRenderer } = require('vue-server-renderer')const renderer = createBundleRenderer(serverBundle, {
runInNewContext: false, // 推荐
template, // (可选)页面模板
clientManifest // (可选)客户端构建 manifest
})
通过上面的 createBundleRenderer 方法生产 render 对象最终将 bunlde 渲染为字符串,将最终的 html 返回给客户端。
bundleRenderer.renderToString([context, callback]): ?Promise<string>step3 添加 entry-client.js,entry-server.js 入口文件
在 src 中除了这两个入口文件,其他的文件都是在客户端和服务端公用的。来看下这两个入口文件中分别干了什么。
大体的流程就是:服务端创建 vue 实例,将页面中的异步请求的数据拿到存储在容器中 –> 客户端接收到服务端发送的 html 以激活模式进行挂载,自动给根元素 #app 上添加
data-server-rendered="true" 特殊属性main.js
import Vue from 'vue'
import App from './App.vue'
...
export function createApp() {
// ...
const app = new Vue({
router,
store,
render: h => h(App)
})
return { app, router, store }
}entry-server.js
import { createApp } from './main.js'
export default context => {
// 因为有可能会是异步路由钩子函数或组件,所以我们将返回一个 Promise,
// 以便服务器能够等待所有的内容在渲染前,
// 就已经准备就绪。
return new Promise((resolve, reject) => {
const { app, router, store } = createApp()
// 设置服务器端 router 的位置
router.push(context.url) // 等到 router 将可能的异步组件和钩子函数解析完
router.onReady(() => {
const matchedComponents = router.getMatchedComponents()
// 匹配不到的路由,执行 reject 函数,并返回 404
if (!matchedComponents.length) {
return reject({ code: 404 })
}
Promise.all(
matchedComponents.map(component => {
if (component.asyncData) {
return component.asyncData({
store,
context,
route: router.currentRoute
})
}
})
).then(() => {
// 在所有预取钩子(preFetch hook) resolve 后,
// 我们的 store 现在已经填充入渲染应用程序所需的状态。
// 当我们将状态附加到上下文,
// 并且 `template` 选项用于 renderer 时,










