解决nuxt3中scroll组件渲染报错:document is not defined
现象:
?我敢说这是nuxt3中出现的最让人头痛的问题之一,非常难搞。
原因:被渲染组件中使用了dom原生api,但是它的代码却打包到ssr服务端环境中,众所周知服务端环境(node环境)是没有window/document/navigator这些原生js对象的。
解决办法有三种:
方法一(不推荐): 使用ClientOnly标签把该组件中存在document渲染问题的html部分包裹住
The?
<ClientOnly>
?component renders its slot only in client-side. To import a component only on the client, register the component in a client-side only plugin.
这种方法不是很推荐,因为这个方法太简单粗暴,严重怀疑会把本不应该做csr的代码打包进浏览器客户端js中,这样减少了服务端渲染的展现量,也加重了客户端的打包体积。
而且每个有问题的组件都要加上ClientOnly标签
方法二(不推荐)、用一个变量isClient来判断是否为浏览器环境,然后用v-if判断是否显示scoll组件,同时在onMount挂载之前通过process.client给isClient赋值。
?<wrap-scroll v-if="isClient" ?class="recommend-content">
?xxxx
interface State extends RecommendResp {?
? isClient: boolean | false;
}
?const state = reactive<State>({?
? ? ? isClient: false
? ? });
? ?onMounted(() => {? ? ??
? ? ? state.isClient = process.client? ? ?
? ? });
这种方法也不是很推荐,因为增加了代码量,而且每个用到scroll组件的页面都要这样添加代码。
方法三(推荐): 从问题根源入手,在scroll组件本身,通过process.client判断是否浏览器环境,是浏览器环境才执行组件代码:
setup(props, { emit }) {
if (process.client) { // 仅在浏览器环境才执行组件代码
const rootRef = ref<HTMLDivElement>(document.createElement("div"));
const scroll = useScroll(rootRef, props, emit);
return {
rootRef,
scroll,
};
}
},
注意必须是在scroll根组件做浏览器环境判断!
在包装组件wrapper做这种判断没有用!
这样就能从根本解决问题,修改这一个地方就够了!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!