常用的基于vue/react的服务端渲染方案,如下:
文档:
pnpm install vue
example.js
// 此文件运行在 Node.js 服务器上
import { createSSRApp } from "vue";
// Vue 的服务端渲染 API 位于 `vue/server-renderer` 路径下
import { renderToString } from "vue/server-renderer";
const app = createSSRApp({
data: () => ({ count: 1 }),
template: `<button @click="count++">{{ count }}</button>`,
});
renderToString(app).then((html) => {
console.log(html);
});
运行
$ node example.js
<button>1</button>
项目结构
$ tree -I node_modules
.
├── app.js
├── client.js
├── index.html
├── package.json
└── server.js
package.json
{
"type": "module",
"dependencies": {
"express": "^4.18.1",
"twig": "^1.15.4",
"vue": "^3.2.40",
"vue-server-renderer": "^2.7.10"
}
}
服务端 server.js
// server.js
import express from "express";
import Twig from "twig";
import { renderToString } from "vue/server-renderer";
import { createApp } from "./app.js";
const server = express();
// 设置模板引擎
server.engine("html", Twig.renderFile);
server.set("view engine", "html");
server.set("views", "./");
server.get("/", (req, res) => {
const app = createApp();
renderToString(app).then((html) => {
res.render("index.html", {
html: html,
});
});
});
// 托管客户端文件
server.use(express.static("."));
server.listen(3000, () => {
console.log("server: http://localhost:3000");
});
app.js
// app.js (在服务器和客户端之间共享)
import { createSSRApp } from "vue";
export function createApp() {
return createSSRApp({
data() {
return {
count: 1,
};
},
template: `<button @click="handleClick">+{{ count }}</button>`,
methods: {
handleClick() {
this.count++;
},
},
created() {
// server client
console.log("created");
},
mounted() {
// client
console.log("mounted");
},
});
}
客户端
// client.js
import { createApp } from "./app.js";
createApp().mount("#app");
index.html
<!DOCTYPE html>
<html>
<head>
<title>Vue SSR Example</title>
<script type="importmap">
{
"imports": {
"vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js"
}
}
</script>
<script type="module" src="/client.js"></script>
</head>
<body>
<div id="app">{{html}}</div>
</body>
</html>
启动服务
$ node server.js
访问地址:http://localhost:3000/
渲染后返回的html
<!DOCTYPE html>
<html>
<head>
<title>Vue SSR Example</title>
<script type="importmap">
{
"imports": {
"vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js"
}
}
</script>
<script type="module" src="/client.js"></script>
</head>
<body>
<div id="app"><button>+1</button></div>
</body>
</html>
其他方案