解决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做这种判断没有用!

这样就能从根本解决问题,修改这一个地方就够了!

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值