Vue中Promise懒加载属性场景下单元素触发重渲染失效问题咨询
问题根因
- Vue只有在感知到响应式数据变化时,才会触发对应视图的重渲染流程,之后才会进入diff阶段对比key的差异。你在
reload方法中修改的watchMe是函数内部的局部非响应式变量,Vue完全感知不到它的变化,根本不会触发重渲染流程,自然也不会去比对key是否更新。 - 你返回的
watchMe是对象引用,即使修改了内部的done属性,key对应的引用本身没有发生变化,Vue判断key值没有变更,就算触发了重渲染也不会重新渲染这个元素。 - 你之前尝试修改局部基础类型变量、行索引的操作,本质都是修改非响应式的局部变量,Vue无法感知,自然不会生效。
最优解决方案:封装独立的单元格组件
将每个需要懒加载的单元格抽离为独立小组件,利用组件自身的响应式状态实现仅单个单元格的局部更新,不会影响其他元素的渲染。
父组件模板
<!-- 父组件内渲染逻辑 --> <template v-for="(row, i) in data" :key="i"> <div class="row"> <template v-for="column in columns" :key="column"> <LazyCell :row="row" :column="column" /> </template> </div> </template>
LazyCell 组件代码
<template> <div> <div v-if="isLoading">Loading...</div> <div v-else>{{ row[column] }}</div> </div> </template> <script> export default { props: ['row', 'column'], data() { return { isLoading: false } }, created() { const cellValue = this.row[this.column] if (cellValue instanceof Promise) { this.isLoading = true cellValue.then(() => { // 仅修改当前组件的响应式状态,只会触发当前组件重渲染 this.isLoading = false }) } } } </script>
这个方案完全符合你的需求:每个单元格加载完成后只会更新自身,不会触发整个组件的重渲染,也不需要修改你原有的自定义getter逻辑。
内容的提问来源于stack exchange,提问作者Randy Hall
相关产品推荐
相关产品推荐

