vue-virtual-scroller中DynamicScroller嵌套展开面板异常问题
解决DynamicScroller中Vuetify展开面板状态错乱问题
这个问题的核心是虚拟滚动组件会复用DOM元素,如果展开状态存在ToDoItem组件内部,滚动或操作时组件复用时就会把状态带到其他item上,导致展开面板串开。加上你之前可能没把key绑定到正确的位置,所以问题没解决。
直接按以下步骤修改:
给每个ToDo项添加独立的展开状态
在你的toDos数组的每个对象里新增isExpanded字段,用来单独控制每个项的展开状态,比如:// 初始化或获取数据时处理 this.toDos = this.toDos.map(todo => ({ ...todo, isExpanded: false }))正确绑定key到DynamicScrollerItem和ToDoItem
虚拟滚动里必须用item的唯一标识(比如id)作为key,不能用index,因为index会随着滚动复用变化。修改模板:<DynamicScroller :items="toDos" :min-item-size="190" class="scroller pr-3 fill-height"> <template v-slot="{ item, index, active }"> <DynamicScrollerItem :item="item" :active="active" :data-index="index" :key="item.id" <!-- 绑定item的唯一标识 --> > <ToDoItem :toDo="item" :is-expanded="item.isExpanded" <!-- 传递展开状态 --> @updateToDo="updateToDo" @toggle-expand="toggleExpand(item)" <!-- 监听展开切换事件 --> :key="item.id" <!-- ToDoItem也绑定唯一key --> /> </DynamicScrollerItem> </template> </DynamicScroller>修改ToDoItem组件,接收外部状态并触发事件
把ToDoItem内部的展开状态改成由父组件传入,点击展开按钮时触发事件通知父组件更新:<!-- ToDoItem.vue --> <template> <v-expansion-panel :value="isExpanded"> <v-expansion-panel-header @click="$emit('toggle-expand')"> {{ toDo.title }} </v-expansion-panel-header> <v-expansion-panel-content> <!-- 你的面板内容 --> </v-expansion-panel-content> </v-expansion-panel> </template> <script> export default { props: { toDo: Object, isExpanded: Boolean }, emits: ['toggle-expand', 'updateToDo'] // 其他原有逻辑... } </script>父组件实现toggleExpand方法
在父组件里添加方法来切换对应item的展开状态:methods: { toggleExpand(item) { // 确保响应式更新,如果直接修改不生效,改用this.$set this.$set(item, 'isExpanded', !item.isExpanded) }, updateToDo(updatedTodo) { // 你的原有更新逻辑 } }
这样修改后,每个ToDo项的展开状态都绑定到自身的数据字段,不会因为虚拟滚动的组件复用而串开,同时正确的key也能帮助Vue识别每个组件的唯一性,避免复用错误。
内容的提问来源于stack exchange,提问作者Mohammed Marjan
相关产品推荐
相关产品推荐

