初步实现方案探索(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