uni-app自定义组件v-if包含video/scroll-view出现错误(不影响使用)

发布于 1周前 作者 caililin 来自 Uni-App

uni-app自定义组件v-if包含video/scroll-view出现错误(不影响使用)

<p>Uncaught TypeError: Cannot read properties of null (reading 'childNodes') at uni-app-view.umd.js:7</p>

<a href="https://www.itying.com/uniimg.php?url=https://img-cdn-tc.dcloud.net.cn/uploads/questions/20241130/8100e7c1ba8c9e0aab19dc16c85792d2.png" target="_blank" data-fancybox-group="thumb" rel="lightbox"><img src="https://www.itying.com/uniimg.php?url=https://img-cdn-tc.dcloud.net.cn/uploads/questions/20241130/8100e7c1ba8c9e0aab19dc16c85792d2.png" alt=""></a>

1 回复

在处理uni-app自定义组件中,如果v-if条件渲染包含videoscroll-view组件时出现错误(尽管不影响功能使用),这通常可能是由于组件的生命周期管理和条件渲染的时机不匹配导致的。这里提供一些可能的代码示例和解释,帮助你理解和解决这类问题。

示例代码分析

自定义组件(MyComponent.vue)

<template>
  <view>
    <video v-if="showVideo" src="video-url" controls></video>
    <scroll-view v-if="showScrollView" scroll-y="true">
      <view v-for="item in items" :key="item.id">{{ item.name }}</view>
    </scroll-view>
    <button @click="toggleVideo">Toggle Video</button>
    <button @click="toggleScrollView">Toggle ScrollView</button>
  </view>
</template>

<script>
export default {
  data() {
    return {
      showVideo: false,
      showScrollView: false,
      items: Array.from({ length: 20 }, (_, i) => ({ id: i, name: `Item ${i + 1}` }))
    };
  },
  methods: {
    toggleVideo() {
      this.showVideo = !this.showVideo;
    },
    toggleScrollView() {
      this.showScrollView = !this.showScrollView;
    }
  }
};
</script>

问题分析

  1. 组件加载时机v-if在条件为false时,会完全移除DOM元素,当条件变为true时,会重新创建DOM元素。这可能导致videoscroll-view组件在重新创建时触发一些生命周期事件或内部状态重置,从而产生错误。

  2. 性能考虑:频繁地创建和销毁大型组件(如videoscroll-view)可能会影响性能。

改进建议(不使用v-if,改用v-show

如果错误不影响功能且主要是出于性能或避免重渲染的考虑,可以考虑使用v-show替代v-if,因为v-show只是切换CSS的display属性,不会销毁和重建DOM元素。

<video v-show="showVideo" src="video-url" controls></video>
<scroll-view v-show="showScrollView" scroll-y="true">
  <!-- 内容 -->
</scroll-view>

这样,组件会始终存在于DOM中,只是根据v-show的值来显示或隐藏,从而避免了因组件重新创建而可能引发的错误。不过,需要注意的是,v-show不会释放不使用的组件资源,对于大型组件或需要频繁切换显示的场景,可能需要权衡使用。

回到顶部