uni-app 动态组件切换+swiper导致页面显示错误
uni-app 动态组件切换+swiper导致页面显示错误
示例代码:
以下代码为我复现的demo,不是实际代码,实际代码更为复杂
以下代码在浏览器中测不出来我说的效果,需要在真机或者手机模拟器中运行
在父组件中通过 component :is
实现动态切换组件
<view class="nav_item" v-for="tab in tabs" :key="tab.id"
:class="{
on: currentTab === tab.id
}"
:data-id="tab.id"
@click="changeTab(tab)"
>{{ tab.text }}</view>
<component ref='child' :is="currentComponents" ></component>
import Activity from '/components/story/activity.vue';
import Everyone from '/components/story/everyone.vue';
import Recommend from '/components/story/recommend.vue';
const tab = [{
id: 'activity',
text: '活动',
component: Activity,
}.....]
const currentTab = ref('recommend');
const currentComponents = computed(() => tabs.find(tab => tab.id === currentTab.value).component);
const changeTab = (tab) => {
currentTab.value = tab.id;
}
Activity 组件中
<view class="activity">
活动
</view>
Recommend 组件中
<swiper indicator-dots>
<swiper-item>
<view class="swiper-item">推荐 内容一</view>
</swiper-item>
<swiper-item>
<view class="swiper-item">推荐 内容二</view>
</swiper-item>
</swiper>
Everyone 组件中
<swiper indicator-dots>
<swiper-item>
<view class="swiper-item">大家 内容一</view>
</swiper-item>
<swiper-item>
<view class="swiper-item">大家 内容二</view>
</swiper-item>
</swiper>
操作步骤:
- Recommend 切换到Everyone
- Recommend 切换到Activity 再切换到Everyone
预期结果:
两个都正常
实际结果:
- 内容重叠,滑动轮播溢出容器隐藏
- 正常
bug描述:
在对组件切换时,如果当前组件和目标组件都存在swiper,就会报错“Uncaught TypeError: Cannot read property ‘children’ of null at uni-app-view.umd.js:7”,并且目标组件的swiper内容全部重叠在一起,对swiper左右切换时,不管是往左还是往右在css中都是translateX(100%),直接溢出容器外部隐藏。
如果目标组件不存在swiper或者当前组件不存在swiper,切换时正常显示。
如果在swiper里面内容复杂,比如再次嵌套swiper,组件切换时内容直接没有了
举例:
a(有swiper) -> b(有swiper) 报错,并且内容重叠,滑动轮播溢出容器隐藏
a(有swiper) -> c(无swiper) -> b(有swiper) 正常
解决方案:改成 v-show
的方式(v-if
和 动态组件一样)或者其他方式实现 tab 栏切换
总结:我觉得是因为动态切换组件时,会卸载之前的组件,而之前组件中的swiper还在操作dom信息,由于组件已经卸载,所以是拿不到deom信息的,所以报错Uncaught TypeError: Cannot read property ‘children’ of null at uni-app-view.umd.js:7。而内容显示错误可能是因为swiper没有重新初始化。
如果我的总结不对欢迎各位大佬指点。希望官方尽早解决
信息类别 | 详细信息 |
---|---|
产品分类 | uniapp/App |
PC开发环境操作系统 | Windows |
PC开发环境操作系统版本号 | Windows 11 专业版 24H2 |
HBuilderX类型 | Alpha |
HBuilderX版本号 | 4.63 |
手机系统 | Android |
手机系统版本号 | Android 15 |
手机厂商 | vivo |
手机机型 | iqoo neo8 |
页面类型 | vue |
vue版本 | vue3 |
打包方式 | 云端 |
项目创建方式 | HBuilderX |
更多关于uni-app 动态组件切换+swiper导致页面显示错误的实战教程也可以访问 https://www.itying.com/category-93-b0.html
更多关于uni-app 动态组件切换+swiper导致页面显示错误的实战教程也可以访问 https://www.itying.com/category-93-b0.html
这是一个典型的动态组件切换导致的Swiper组件状态异常问题。主要原因如下:
-
动态组件切换时(
component:is
),会销毁旧组件并创建新组件,导致Swiper实例被销毁但可能仍有未完成的DOM操作 -
当两个组件都包含Swiper时,切换过程中Swiper的销毁和初始化可能产生冲突,特别是当第一个Swiper的动画未完成时就切换到第二个Swiper时
解决方案建议:
- 使用
v-show
替代动态组件切换(已验证有效):
<Activity v-show="currentTab === 'activity'"/>
<Recommend v-show="currentTab === 'recommend'"/>
<Everyone v-show="currentTab === 'everyone'"/>
- 如果必须使用动态组件,可以在切换时强制销毁Swiper:
const changeTab = (tab) => {
// 先重置currentComponents为null
currentComponents.value = null
nextTick(() => {
currentTab.value = tab.id
})
}
- 给每个Swiper添加唯一的key:
<swiper :key="'swiper-'+currentTab">