uni-app自定义组件v-if包含video/scroll-view出现错误(不影响使用)
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
条件渲染包含video
或scroll-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>
问题分析
-
组件加载时机:
v-if
在条件为false
时,会完全移除DOM元素,当条件变为true
时,会重新创建DOM元素。这可能导致video
或scroll-view
组件在重新创建时触发一些生命周期事件或内部状态重置,从而产生错误。 -
性能考虑:频繁地创建和销毁大型组件(如
video
或scroll-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
不会释放不使用的组件资源,对于大型组件或需要频繁切换显示的场景,可能需要权衡使用。