Vue3组件列表更新后data变量未同步更新问题求助
问题描述
通过CDN使用Vue3开发组件时遇到如下问题:
循环渲染代码:
<div v-for="product in products"> <product-tyre-list-card :product="product" :min="product.minimum"></product-tyre-list-card> </div>
product-tyre-list-card组件代码:
export default { props: { product: Object, min: Number }, data() { return { quantity: this.min } }, methods: { decrease() { if(this.quantity > this.product.minimum) this.quantity--; }, increase() { this.quantity++; } }, template: `<input v-model="quantity">` }
场景还原:
- 首次请求服务器获取products数组:
此时三个卡片输入框显示2、2、1,符合预期。[ { id: 1, minimum: 2 }, { id: 2, minimum: 2 }, { id: 3, minimum: 1 } ] - 应用筛选条件后,重新获取新的products数组:
页面显示新卡片,但输入框仍显示旧值2、2、1,而非预期的5、5、5。[ { id: 5, minimum: 5 }, { id: 6, minimum: 5 }, { id: 7, minimum: 5 } ]
原因分析
这是Vue的组件复用机制导致的:
- Vue渲染
v-for列表时,为了提升性能会复用已有组件实例,而非销毁旧实例重新创建。 - 你的组件中
quantity仅在data()初始化时赋值为this.min,组件复用后data不会重新初始化,只会更新props,因此quantity保留着旧的初始值。
解决方案
有两种常用解决方法:
方法一:给v-for添加唯一key,强制替换组件
修改循环代码,给v-for加上:key="product.id",让Vue根据唯一id识别组件是否需要替换:
<div v-for="product in products" :key="product.id"> <product-tyre-list-card :product="product" :min="product.minimum"></product-tyre-list-card> </div>
新products数组的id与旧数据完全不同时,Vue会销毁旧组件实例并创建新实例,此时data会重新初始化,quantity会取新的min值。
方法二:监听props变化,主动更新quantity
如果不想销毁重建组件,可以在组件内监听min或product.minimum的变化,同步更新quantity:
export default { props: { product: Object, min: Number }, data() { return { quantity: this.min } }, watch: { // 监听min props的变化 min(newVal) { this.quantity = newVal; }, // 若product对象整体替换,需开启深度监听 product: { handler(newProduct) { this.quantity = newProduct.minimum; }, deep: true } }, methods: { decrease() { if(this.quantity > this.product.minimum) this.quantity--; }, increase() { this.quantity++; } }, template: `<input v-model="quantity">` }
组件复用后,props更新时quantity会同步为新的最小值。
内容的提问来源于stack exchange,提问作者expream
相关产品推荐
相关产品推荐

