list-view组件的list-item通过组件实现,组件在变更data属性报错
list-view组件的list-item通过组件实现,组件在变更data属性报错
开发环境 | 版本号 | 项目创建方式 |
---|---|---|
Windows | win10 | HBuilderX |
bug描述:
list-view组件的list-item通过组件实现,组件在变更data属性报错
如果页面完整的使用list-view(不将list-item代码移到组件)就能正常执行
点击 切换文本,会报错,如下图
示例代码:
<template>
<view style="flex: 1;background-color: #d1d1d1;">
<list-view :scroll-y="true" class="page" bounces="true" show-scrollbar="true" style="flex: 1;" >
<list-item class="content-item" style="height: 200px;;">
<text class="text">向上滑动页面,体验sticky-header吸顶效果。</text>
</list-item>
<sticky-item></sticky-item>
</list-view>
</view>
</template>
<script>
export default {
}
</script>
<template>
<sticky-header>
<scroll-view style="background-color: #f5f5f5; flex-direction: row;" direction="horizontal" show-scrollbar="false">
<view style="align-self: flex-start; flex-direction: row;">
<text ref="swipertab" style="padding-right: 20px;height: 30px;" v-for="index in 5" @click="clickTH(index)">
DAAA{{index}}
</text>
</view>
</scroll-view>
</sticky-header>
<list-item>
<swiper :current-item-id="currentItemId">
<swiper-item v-for="i in 5" :item-id="'itemid'+i">
<view v-for="index in 10" :key="index">
<text style="height: 80px;">{{i}}==>{{index}}</text>
</view>
</swiper-item>
</swiper>
</list-item>
</template>
<script>
export default {
name: "stick-item",
data() {
return {
currentItemId: "itemid0"
}
},
methods: {
clickTH: function (index : number) {
console.log(index);
this.currentItemId = "itemid" + index
}
}
}
</script>
操作步骤:
可正常执行
预期结果:
可正常执行
实际结果:
执行报错:
22:14:34.006 java.lang.NullPointerException
at io.dcloud.uniapp.vue.IndexKt$setupRenderEffect$componentUpdateFn$1.invoke(index.kt:6509)
...
6 回复
问题复现,感谢反馈,已加分
方便发个可复现demo嘛
忘了说,需要点击切换文本触发事件才会报错,请看上图,demo.zip 还是一样会报错
暂时可通过把 list-view 及子节点封装到一个组件中规避该问题
频道页面就是一个list-view,每个频道页都不一样,吸顶前面的内容完全不同,吸顶后面的内容才是一样的,
这个错误是由于在list-item组件中直接修改data属性导致的渲染问题。在uni-app的list-view组件中,list-item的子组件需要特别注意数据更新的方式。
问题出在stick-item组件中,当点击切换文本时直接修改了currentItemId属性,而这种方式在list-view的子组件中可能会导致渲染异常。
建议的解决方案:
- 使用$set方法更新数据:
clickTH: function(index) {
this.$set(this, 'currentItemId', "itemid" + index)
}
- 或者使用Vue.set:
import Vue from 'vue'
// ...
clickTH: function(index) {
Vue.set(this, 'currentItemId', "itemid" + index)
}