我正在将 Vite JS 与 Vue 3 一起用于具有服务器端渲染的单页应用程序。
我知道只能在客户端执行的 JS 必须在 hydration 上完成,但是是否可以使用包来完成?
我的情况是我希望能够使用 Headless UI(用于 Tailwind UI),只要应用程序作为单页应用程序启动,它就可以正常工作。使用 SSR 启动时,会出现以下错误:
[Vue warn]: Unhandled error during execution of setup function
at <Dialog as="div" static="" class="fixed z-10 inset-0 overflow-y-auto" ... >
ReferenceError: window is not defined
at useWindowEvent (C:\test\node_modules\.pnpm\@headlessui+vue@1.2.0_vue@3.0.11\node_modules\@headlessui\vue\dist\headlessui.cjs.development.js:408:3)
at useFocusTrap (C:\test\node_modules\.pnpm\@headlessui+vue@1.2.0_vue@3.0.11\node_modules\@headlessui\vue\dist\headlessui.cjs.development.js:486:3)
at setup (C:\test\node_modules\.pnpm\@headlessui+vue@1.2.0_vue@3.0.11\node_modules\@headlessui\vue\dist\headlessui.cjs.development.js:1052:5)
at callWithErrorHandling (C:\test\node_modules\.pnpm\@vue+runtime-core@3.0.11\node_modules\@vue\runtime-core\dist\runtime-core.cjs.js:156:22)
at setupStatefulComponent (C:\test\node_modules\.pnpm\@vue+runtime-core@3.0.11\node_modules\@vue\runtime-core\dist\runtime-core.cjs.js:6488:29)
at setupComponent (C:\test\node_modules\.pnpm\@vue+runtime-core@3.0.11\node_modules\@vue\runtime-core\dist\runtime-core.cjs.js:6449:11)
at renderComponentVNode (C:\test\node_modules\.pnpm\@vue+server-renderer@3.0.11_vue@3.0.11\node_modules\@vue\server-renderer\dist\server-renderer.cjs.js:160:17)
at renderVNode (C:\test\node_modules\.pnpm\@vue+server-renderer@3.0.11_vue@3.0.11\node_modules\@vue\server-renderer\dist\server-renderer.cjs.js:263:22)
at renderComponentSubTree (C:\test\node_modules\.pnpm\@vue+server-renderer@3.0.11_vue@3.0.11\node_modules\@vue\server-renderer\dist\server-renderer.cjs.js:228:13)
at renderComponentVNode (C:\test\node_modules\.pnpm\@vue+server-renderer@3.0.11_vue@3.0.11\node_modules\@vue\server-renderer\dist\server-renderer.cjs.js:173:16)
我知道错误来自服务器端无法访问的窗口属性,但这是由包本身设置的。
无论如何告诉Vite JS SSR不要在那个包上执行JS,除非它在客户端?
以下是导致错误的 vue 组件的内容(仅在 SSR 执行时,Dialog 来自 Headless UI):
<template>
<TransitionRoot as="template" :show="open">
<Dialog as="div" static class="fixed z-10 inset-0 overflow-y-auto" @close="open = false" :open="open">
<div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
TEST
</div>
</Dialog>
</TransitionRoot>
</template>
<script>
import { ref } from 'vue'
import { Dialog, TransitionRoot } from '@headlessui/vue'
export default {
components: {
Dialog,
TransitionRoot
},
setup() {
const open = ref(true)
return {
open,
}
},
}
</script>
PS:如果您需要配置参考,我使用了这个样板项目:https ://github.com/frandiox/vitesse-ssr-template