初步实现方案探索(Node环境)
// 第 1 步:创建一个 Vue 实例
const Vue = require('vue')
const app = new Vue({
template: `<div>Hello World</div>`
})
// 第 2 步:创建一个 renderer
const renderer = require('vue-server-renderer').createRenderer()
// 第 3 步:将 Vue 实例渲染为 HTML
renderer.renderToString(app, (err, html) => {
if (err) throw err
console.log(html)
// => <div data-server-rendered="true">Hello World</div>
})
引入vue-server-renderer
,他里面有一个createRenderer
的方法,这个方法里的renderToString
,可以把app渲染成字符串,第一个参数是vue实例,第二个参数是回调(错误参数(err),编译好的字符串(html))。
非node环境实现服务端渲染(例如j2v8)
// entry-server.js
import Vue from "vue";
const renderVueComponentToString = require("vue-server-renderer/basic.js");
console.log("renderVueComponentToString");
console.log(renderVueComponentToString);
// app.js
const vm = new Vue({
template: `<div>{{ msg }}</div>`,
data: {
msg: "hello"
}
});
console.log("data.msg:" + vm.$data.msg);
console.log("renderVueComponentToString");
console.log(renderVueComponentToString);
global.renderServer = context => {
console.log("context:" + JSON.stringify(context));
return new Promise((resolve, reject) => {
renderVueComponentToString(vm, context, (err, res) => {
if (err) {
console.log(err);
reject(err);
}
resolve(res);
console.log(res);
});
});
};
// test-entry-server.js
require("../../src/ssr/entry-server")
const context = {
url: "/"
};
const promise = global.renderServer(context);
console.log("promise");
console.log(promise);
promise.then(
value => {
console.log(value);
},
reason => {
console.log(reason);
}
);
运行结果
➜ webapp git:(develop) ✗ yarn babel-node ./tests/ssr/test-entry-server.js --presets=@babel/preset-env
yarn run v1.13.0
$ /mnt/c/Users/Terwer/IdeaProjects/jvue-cli/src/main/webapp/node_modules/.bin/babel-node ./tests/ssr/test-entry-server.js --presets=@babel/preset-env
renderVueComponentToString
[Function: renderToString]
data.msg:hello
renderVueComponentToString
[Function: renderToString]
context:{"url":"/"}
<div data-server-rendered="true">hello</div>
promise
Promise { '<div data-server-rendered="true">hello</div>' }
<div data-server-rendered="true">hello</div>
Done in 3.63s.
Github
https://github.com/terwer/jvue
https://github.com/terwer/jvue-cli