vue.js - 如何在 Vue 3 中使用 SSR
问题描述
我有一个具有服务器端渲染功能的 Vue 2 应用程序。现在我正在尝试升级到 Vue 3,但卡在 SSR 部分,因为 vue-server-renderer 包会引发以下错误:
Vue packages version mismatch: - vue@3.0.0 - vue-server-renderer@2.6.12 This may cause things to work incorrectly. Make sure to use the same version for both.
但是 vue-server-renderer 没有 3.0.0 版本...
通过谷歌搜索,我在 vue-next 存储库中发现了这个问题:https ://github.com/vuejs/vue-next/issues/1327
但对我来说,如何使用 vue 3 版实现 SSR 仍不清楚。已经可以了吗?有没有一个如何在 Vue 3 中使用 SSR 的例子?
解决方案
Vue-server-renderer 只能与 vue 版本 2 一起使用。版本 3 的一大变化是它现在支持 SSR。
因此,您现在只需使用 vue 的createSSRApp
. 在服务器上,要将由此创建的应用程序呈现为可以发送到浏览器的字符串,您可以使用renderToString
可以从中导入的方法@vue/server-renderer
(请注意,您必须单独安装此包)。
作为一个超级基本(没有捆绑器或任何东西)的例子,这看起来像这样:
const express = require('express');
const { createSSRApp } = require('vue');
const { renderToString } = require('@vue/server-renderer');
const app = express();
const example= {
template: `
<div>
Hello World
</div>`,
};
function renderVueApp(req, res) {
const vueApp = createSSRApp(example);
(async () => {
const html = await renderToString(vueApp);
res.send(`
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://unpkg.com/vue@next"></script>
<title>About blank</title>
</head>
<body>
<div id="app">${html}</div>
<script>
const example = { template: '<div>Hello World</div>};
Vue.createSSRApp(example).mount('#app', true);
</script>
</body>
</html>
`);
})();
}
app.get('/', renderVueApp);
const port = process.env.PORT || 8080;
app.listen(port, () =>
console.log(`Server started at localhost:${port}. Press ctrl+c to quit.`)
);
在前端,您让 vue 从服务器接管标记,即您以水合模式创建和挂载应用程序。
您在问题中引用的捆绑渲染器或多或少只是从 vue-2.0 服务器渲染器中提取的。为了使用它,你必须使用 vue-2.0 server-renderer 包中的 client-plugin 和 server-plugin 并将它们插入你的 webpack 进程以获取 server-bundle 和客户端清单。
请注意,使用此设置,捆绑渲染器将仅注入 rel="preload" 的条目/初始脚本。现在,“新”vue-loader 不会将任何组件注册逻辑注入到组件中(就像“旧”vue 加载器一样)。尽管如此,只要在ssrContext._registeredComponents
. 因此,如果您在应用程序中需要此功能,则必须自己编写该逻辑。
当然,这是一种方法。我敢肯定还有更多的道路通往同一个目的地。
我写了一个 vue3 版本的 vue2 hackernews 克隆,它使用了所有描述/提到的东西。
推荐阅读
- django - 创建帐户后,Django用户无法登录,但管理员可以
- javascript - 如何从一组照片中创建一个 base64 数组
- c# - c# winforms clickonce分别下载不同的环境应用?
- c# - 在动态对象上设置属性的通用方法
- elasticsearch - 按未找到但该字段存在的现有字段搜索 Elasticsearch 文档
- javascript - Web OTP api 给出 DOMException:OTP 检索超时
- angular - 可观察的抽象类未触发,Angular 11 ts 4
- django-templates - 表格行中的下拉列表显示循环中的所有元素
- dart - 如何在 Dart 或 Flutter 中创建点函数
- statistics - Amazon SageMaker Studio Autopilot:在进行时间序列预测时,您是否需要将目标列向后移动?