npm install --save vue-server-renderer vue
API
1. createRenderer()
该方法是创建一个renderer实列。如下代码:
const renderer = require('vue-server-renderer').createRenderer();
2. renderer.renderToString(vm, cb);
该方法的作用是:将Vue实列呈现为字符串。该方法的回调函数是一个标准的Node.js回调,它接收错误作为第一个参数。代码略。
3. createBundleRenderer(code, [rendererOptions])
Vue SSR依赖包 vue-server-render, 它的调用支持有2种格式,createRenderer() 和 createBundleRenderer(), 那么createRenderer()是以vue组件为入口的,而 createBundleRenderer() 以打包后的JS文件或json文件为入口的。所以createBundleRenderer()的作用和 createRenderer() 作用是一样的,无非就是支持的入口文件不一样而已;我们可以简单的使用 createBundleRenderer该方法来做个demo如下:
const createBundleRenderer = require('vue-server-renderer').createBundleRenderer; // 绝对文件路径 let renderer = createBundleRenderer('./package.json'); console.log(renderer);
在我们div中有一个特殊的属性 data-server-rendered,该属性的作用是告诉VUE这是服务器渲染的元素。并且应该以激活的模式进行挂载。
从上面的知识学习,我们了解到要服务器端渲染,我们需要用到 vue-server-renderer 组件包。该包的基本的作用是拿到vue实列并渲染成html结构。
因此我们需要在我们项目的根目录下新建一个叫app.js ,把上面的html代码抽离出来成一个 index.template.html
在app.js里,通过node中的 fs模块读取 index.template.html 页面代码进去
注意:html中必须包含 <!--vue-ssr-outlet--> ,renderer.renderToString函数把这行代码替换成HTML. 我之前以为这只是一个注释,然后随便写一个注释上去,结果运行命令报错,改成这个 <!--vue-ssr-outlet--> 就可以了,因此这个的作用就是当做占位符,等 renderer.renderToString函数 真正渲染成html后,会把内容插入到该地方来。
服务器渲染过程中,只会调用 beforeCreate 和 created两个生命周期函数。其他的生命周期函数只会在客户端调用。
我们Node.js 服务器是一个长期运行的进程,当我们运行到该进程的时候,它会将进行一次取值并且留在内存当中,如果我们用单列模式来创建对象的话,那么它的实列,会让每个请求之间会发生共享。也就是说实列发生共享了,那么这样很容易导致每个实列中的状态值会发生混乱。因此我们这边把app.js代码抽离一份出来,就是需要为每个请求创建一个新的实列。因此我们会把上面的demo代码分成两部分。
新建server.js ,如上server.js 代码会引用 app.js,如代码:const createApp = require('./src/app'); 然后在 router.get('*', async(ctx, next) => {}) 里面都会调用下 const app = createApp(ctx); 这句代码,创建一个新的实列。
app.js :为每个请求创建一个新的根vue实列
因为可能存在异步组件,所以等待router将所有异步组件加载完毕,服务器端配置也需要此操作
如上所说,我们只是使用 node server.js 运行服务器端的启动程序,然后进行服务器端渲染页面,但是我们并没有将相同的vue代码提供给客户端,因此我们要实现这一点的话,我们需要在项目中引用我们的webpack来打包我们的应用程序。