VueJS更新前显示旧图片问题 分页及v-autocomplete旧图残留如何解决
问题根因
- 核心原因是你
v-for循环使用数组索引i作为key值:当你切换分页时,同一索引位置的DOM元素会被Vue复用。比如第1页第一个商品对应key=0,第2页第一个商品对应key仍然是0,Vue会判定为同一个DOM节点,只会更新<img>标签的src属性,不会重新创建DOM。此时新的图片资源还在加载过程中,旧的图片资源还保留在DOM节点上,就会出现新旧内容不匹配的问题。 - Vuetify的
v-autocomplete出现同样问题也是相同逻辑:你没有给组件设置唯一的item-key属性,组件默认复用同位置的DOM节点,导致图片残留。
解决方法
1. 替换v-for的key值为唯一标识
把:key="i"替换为商品的唯一ID,比如product.id(只要是商品维度的唯一值都可以),这样不同商品对应的key完全不同,切换分页时Vue会直接销毁旧DOM、创建新的DOM节点,不会出现旧图片残留的问题。
如果商品确实没有全局唯一ID,也可以把分页页码和索引拼接作为key::key="${page}-${i}",切换页码时同一位置的key也会变化,同样可以触发DOM重建。
2. 可选:增加图片加载状态控制
如果希望加载过程中完全空白或者显示骨架屏,可以额外监听图片的load事件控制显隐,修改后代码参考:
<div v-for="product in productsByIDPaginated" :key="product.id" > <template v-if="product.imagesNumber > 0"> <!-- 未加载完成时不显示,你也可以替换为骨架屏组件 --> <img v-show="product.imgLoaded" @click.stop="toProductDetailsPage(product)" :src="imageUrl(product)" @error="replaceByDefault" @load="product.imgLoaded = true" /> </template> <img v-else @click="toProductDetailsPage(product)" src="../assets/unknown2.jpg" /> </div> <script> productsByIDPaginated() { // 给每个商品添加默认的imgLoaded状态,避免跨页状态污染 return this.productsByIDFiltred.slice( this.numberProdsByPage * (this.page - 1), this.numberProdsByPage * this.page ).map(item => ({...item, imgLoaded: false})); }, </script>
3. 修复v-autocomplete的问题
给v-autocomplete组件设置item-key属性为商品的唯一ID即可:
<v-autocomplete <!-- 其他原有属性保持不变 --> item-key="id" <!-- 替换为你商品的唯一ID字段名 --> ></v-autocomplete>
内容的提问来源于stack exchange,提问作者Imu Sama
相关产品推荐
相关产品推荐

