首先,Vue.js 是一个用于构建客户端应用的框架。默认情况下 Vue 组件的职责实在客户端浏览器中生成和操作 DOM。
然而,Vue 也支持将组件在服务端直接渲染成 HTML 字符串,并作为服务端响应返回给浏览器,最后在浏览器端将静态的 HTML“激活”为能够交互的客户端应用。————》这种服务端渲染技术就是 SSR。
优势:
你可以使用相同的语言以及相同的声明式、面向组件的心智模型来开发整个应用,而不需要在后端模板系统和前端框架之间来回切换。
限制和劣势:
SSG:静态站点生成,也被称为预渲染,是另一种流行的构建快速网站的技术。
SSR 与 SSG 相同之处:
SSR 与 SSG 区别:
npm init -y生成 package.json,编辑 package.json 文件添加一行"type": "module",修改后的 package.json 文件内容如下:{
"name": "vue-ssr",
"version": "1.0.0",
"type": "module",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.18.2",
"vue": "^3.3.4"
}
}
npm install vuenpm install express第三步 创建 server.js 文件,并写入如下代码:
import express from "express";
import { createSSRApp } from "vue";
// 导入Vue的服务端渲染API
import { renderToString } from "vue/server-renderer";
const server = express();
server.get("/", (req, res) => {
const app = createSSRApp({
data: () => ({ count: 1 }),
template: `<button @click="count++">{{ count }}</button>`,
});
renderToString(app).then((html) => {
res.send(` <!DOCTYPE html>
<html>
<head>
<title>Vue SSR Example</title>
</head>
<body>
<div id="app">${html}</div>
</body>
</html>
`);
});
});
server.listen(3000, () => {
console.log("Server Started....");
});
Vue 的服务端渲染 API
renderToString()接受一个 Vue 应用实例作为参数,返回一个 Promise,当 Promise resolve 时返回应用渲染的 HTML。
第四步 运行 node server.js 启动服务,浏览器访问 http://localhost:3000 ,就可以看到页面中按钮了。
什么是客户端激活呢?
细心的同学可能已发现,上文运行服务端代码后,点击浏览器中的按钮数字并没有自增改变。这是因为这段 HTML 代码在客户端是完全静态的,并没有在浏览器中加载 Vue。
那么为了使客户端的应用可交互,Vue 需要执行一个激活步骤。
在激活过程中,Vue 会创建一个于服务端完全相同的应用实例,然后将每个组件与它应该控制的 DOM 节点相匹配,并添加 DOM 事件监听器。
由于实现激活需要重新组织代码结构(下文的代码结构部分会详解),所以此处先展示一个激活的代码片段:
// 该文件运行在浏览器中
import { createSSRApp } from "vue";
const app = createSSRApp({
// ...和服务端完全一致的应用实例
});
/**
* 在客户端挂载一个 SSR 应用时,会假定 HTML 是预渲染的,然后执行激活过程,而不是挂载新的 DOM 节点
*/
app.mount("#app");
注意 在激活模式下挂载应用,应该使用createSSRApp() 而不是createApp()。
通用代码 app.js
通用代码只是指在客户端和服务端可复用的代码及其依赖项,我们可以把这些拆分到一个或多个独立的文件中。本例中代码逻辑简单,拆分一个 app.js 文件即可:
// app.js
import { createSSRApp } from "vue";
export function createApp() {
return createSSRApp({
data: () => ({ count: 1 }),
template: `<button @click="count++">{{ count }}</button>`,
});
}
客户端入口文件 client.js
// client.js
import { createApp } from "./app.js";
createApp().mount("#app");
服务端入口文件 server.js
运行服务端文件后,为了在浏览器中加载客户端文件,还需要在 server.js 文件中做以下修改:
server.use(express.static('.')) 来托管客户端文件。<script type="module" src="./client.js"></script> 添加到 HTML 外壳以加载客户端入口文件。import * from 'vue'。修改后的 server.js 完整代码如下:
import express from "express";
import { renderToString } from "vue/server-renderer";
import { createApp } from "./app.js";
const server = express();
server.get("/", (req, res) => {
const app = createApp();
renderToString(app).then((html) => {
res.send(`
<!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>
`);
});
});
server.use(express.static("."));
server.listen(3000, () => {
console.log("Server Started....");
});
此时我们一开始创建的文件夹下的代码结构如下:
vue-ssr
|-- app.js
|-- client.js
|-- server.js
|-- package.json
|-- package-lock.json
|-- node_modules
最后重新运行 node server.js,再访问 http://localhost:3000 页面,点击按钮数字就会自增改变了。
由于实现一套完整的 SSR 技术构建会非常复杂,因此建议和推荐大家在通过上面实例教程了解到 SSR 原理之后,选择一些成熟的 SSR 解决方案,以提高工作效率。下面推荐几个 Vue 生态中的 SSR 解决方案。
Nuxt 是一个构建于 Vue 生态系统之上的全栈框架,它为编写 Vue SSR 应用提供了丝滑的开发体验。更棒的是,你还可以把它当作一个静态站点生成器来用!我们强烈建议你试一试。
Quasar 是一个基于 Vue 的完整解决方案,它可以让你用同一套代码库构建不同目标的应用,如 SPA、SSR、PWA、移动端应用、桌面端应用以及浏览器插件。除此之外,它还提供了一整套 Material Design 风格的组件库。
Vite 提供了内置的 Vue 服务端渲染支持,但它在设计上是偏底层的。如果你想要直接使用 Vite,可以看看 vite-plugin-ssr,一个帮你抽象掉许多复杂细节的社区插件。
🔥BuildAdmin是一个永久免费开源,无需授权即可商业使用,且使用了流行技术栈快速创建商业级后台管理系统。