路由处理
在 Vue SSR(Server-Side Rendering)环境中,路由处理和数据预取是两个关键点,它们确保了应用能够根据 URL 正确地渲染页面,并且可以在服务器端获取必要的数据,从而提高首屏加载速度和 SEO 效果。
1. 配置 Vue Router
首先,你需要配置 Vue Router 来管理客户端和服务器端的路由。创建一个 router/index.js 文件来设置路由规则:
javascript
import Vue from "vue";
import Router from "vue-router";
import Home from "@/components/Home.vue";
import About from "@/components/About.vue";
Vue.use(Router);
export function createRouter() {
return new Router({
mode: "history",
routes: [
{ path: "/", component: Home },
{ path: "/about", component: About },
// 其他路由...
],
});
}2. Vue main 文件获取路由
js
// ./src/main.js
import Vue from "vue";
import App from "./App.vue";
import createRouter from "./router/index.js";
export default function () {
const router = createRouter();
const app = new Vue({
render: (h) => h(App),
router, // 确保将 router 挂载到 Vue 实例上
});
return { app, router };
}3. 设置服务器端路由位置
在服务器端入口文件 (entry-server.js) 中,需要设置路由器的位置以匹配当前请求的 URL:
javascript
import { createApp } from "../main";
export default (context) => {
return new Promise((resolve, reject) => {
const { app, router, store } = createApp();
// 设置服务器端路由位置
router.push(context.url);
// 等待所有异步组件和钩子完成
router.onReady(() => {
const matchedComponents = router.getMatchedComponents();
if (!matchedComponents.length) {
return reject({ code: 404 });
}
// 继续进行数据预取和其他操作
resolve(app);
}, reject);
});
};这里我们使用 router.push() 方法将 URL 推送到路由器中,并等待其准备好再继续执行后续逻辑。如果没有任何匹配的组件,我们可以抛出一个 404 错误。
4. 服务端主文件获取路由
js
// ./server/server.js
const express = require("express");
const fs = require("fs");
const { createBundleRenderer } = require("vue-server-renderer");
const serverBundle = require("../dist/vue-ssr-server-bundle.json");
const clientManifest = require("../dist/vue-ssr-client-manifest.json");
const app = express();
app.use(express.static(resolve("../dist")), { index: false });
app.get("*", async (req, res) => {
// 1. 获取请求router
const url = req.url;
try {
// 2. 创建渲染器
const renderer = createBundleRenderer(
serverBundle,
{
template: fs.readFileSync("./index.ssr.html", "utf-8"), // 模板文件
},
clientManifest
);
// 3. 利用渲染器将vue 实例转换成html 字符串,传递url 可以被server 入口函数获取到url
const html = await renderer.renderToString({ url });
res.send(html);
} catch (err) {
console.error(err);
if (err.code === 404) {
res.status(404).send("Page not found");
return;
}
res.status(500).send("Internal Server Error");
}
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});总结
通过正确配置 Vue Router 和实现数据预取机制,你可以确保你的 Vue SSR 应用程序不仅能够根据 URL 正确地渲染页面,而且可以在服务器端获取必要的数据,从而提升性能和用户体验。