SSR 兼容性

您所在的位置:网站首页 clientonly组件 SSR 兼容性

SSR 兼容性

2024-07-10 09:53| 来源: 网络整理| 查看: 265

SSR 兼容性 ​

通过使用 Vue 的服务器端渲染 (SSR) 功能,VitePress 能够在生产构建期间在 Node.js 中预渲染应用程序。这意味着主题组件中的所有自定义代码都需要考虑 SSR 兼容性。

Vue 官方文档的 SSR 部分提供了更多有关 SSR 是什么,SSR / SSG 之间的关系以及编写 SSR 友好代码的常见注意事项等信息。原则上只在 Vue 组件的 beforeMount 或 mounted 钩子中访问 browser / DOM API。

如果你正在使用或演示不支持 SSR 的组件 (例如,包含自定义指令),则可以将它们包装在内置的 组件中:

md 123在导入时访问浏览器 API 的库 ​

一些组件或库在导入时访问浏览器 API。要使用假定在导入时处于浏览器环境的代码,你需要动态导入它们。

在 mounted 钩子中导入 ​vue import { onMounted } from 'vue' onMounted(() => { import('./lib-that-access-window-on-import').then((module) => { // use code }) }) import { onMounted } from 'vue' onMounted(() => { import('./lib-that-access-window-on-import').then((module) => { // use code }) }) 123456789条件导入 ​

你也可以使用 importa.env.SSR 标志 (Vite 环境变量的一部分) 来有条件地导入依赖项:

jsif (!importa.env.SSR) { import('./lib-that-access-window-on-import').then((module) => { // use code }) }if (!importa.env.SSR) { import('./lib-that-access-window-on-import').then((module) => { // use code }) }12345

因为 Theme.enhanceApp 可以是异步的,所以你可以有条件地导入并注册访问浏览器 API 的 Vue 插件:

js// .vitepress/theme/index.js /** @type {import('vitepress').Theme} */ export default { // ... async enhanceApp({ app }) { if (!importa.env.SSR) { const plugin = await import('plugin-that-access-window-on-import') app.use(plugin) } }, }// .vitepress/theme/index.js /** @type {import('vitepress').Theme} */ export default { // ... async enhanceApp({ app }) { if (!importa.env.SSR) { const plugin = await import('plugin-that-access-window-on-import') app.use(plugin) } }, }1234567891011

如果你使用 TypeScript:

ts// .vitepress/theme/index.ts import type { Theme } from 'vitepress' export default { // ... async enhanceApp({ app }) { if (!importa.env.SSR) { const plugin = await import('plugin-that-access-window-on-import') app.use(plugin) } }, } satisfies Theme// .vitepress/theme/index.ts import type { Theme } from 'vitepress' export default { // ... async enhanceApp({ app }) { if (!importa.env.SSR) { const plugin = await import('plugin-that-access-window-on-import') app.use(plugin) } }, } satisfies Theme123456789101112defineClientComponent {#defineclientcomponent} ​

VitePress 为导入 Vue 组件提供了一个方便的辅助函数,该组件可以在导入时访问浏览器 API。

vue import { defineClientComponent } from 'vitepress' const ClientComp = defineClientComponent(() => { return import('component-that-access-window-on-import') }) import { defineClientComponent } from 'vitepress' const ClientComp = defineClientComponent(() => { return import('component-that-access-window-on-import') }) 1234567891011

你还可以将 props/children/slots 传递给目标组件:

vue import { ref } from 'vue' import { defineClientComponent } from 'vitepress' const clientCompRef = ref(null) const ClientComp = defineClientComponent( () => import('component-that-access-window-on-import'), // args are passed to h() - https://vuejs.org/api/render-function.html#h [ { ref: clientCompRef, }, { default: () => 'default slot', foo: () => h('div', 'foo'), bar: () => [h('span', 'one'), h('span', 'two')], }, ], // callback after the component is loaded, can be async () => { console.log(clientCompRef.value) }, ) import { ref } from 'vue' import { defineClientComponent } from 'vitepress' const clientCompRef = ref(null) const ClientComp = defineClientComponent( () => import('component-that-access-window-on-import'), // args are passed to h() - https://vuejs.org/api/render-function.html#h [ { ref: clientCompRef, }, { default: () => 'default slot', foo: () => h('div', 'foo'), bar: () => [h('span', 'one'), h('span', 'two')], }, ], // callback after the component is loaded, can be async () => { console.log(clientCompRef.value) }, ) 123456789101112131415161718192021222324252627282930

The target component will only be imported in the mounted hook of the wrapper component.



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3