小程序中如何让子组件修改父组件传递的数组数据?
大家好,我在做一个购物车小程序,父组件通过prop传了一个商品列表数组给子组件,现在子组件需要点击按钮往这个数组里添加新商品。我用this.$emit把新商品发给父组件,但发现父组件的数组没有更新,控制台也没报错…
export default {
data() { return { cartList: [] }},
methods: {
addItem(newProduct) {
console.log('收到商品:', newProduct) // 能正常收到数据
this.cartList.push(newProduct) // 这里操作了prop?
}
}
}
export default {
props: ['products'],
methods: {
addToCart() {
const newItem = { id: 1, name: '测试品' }
this.$emit('add', newItem) // 直接修改了prop里的数组?
this.products.push(newItem) // 这样写对吗?
}
}
}
我尝试过直接修改prop传来的数组,但控制台提示”[Vue warn] Avoid mutating a prop directly”,改成通过事件传递后虽然没有报错,但页面还是没更新。是不是事件监听写错了?或者需要手动调用this.$forceUpdate?
先说子组件,别直接动
this.products,只管发事件出去就行:然后父组件这边,你得确保正确监听事件并且更新自己的数据。直接改你原来的代码,拿去改改:
关键点是父组件不要直接
push,而是用扩展运算符[...]创建一个新数组,这样能确保Vue的响应式系统检测到变化并更新页面。至于$forceUpdate,根本不用,那是绕开Vue正常机制的下策。另外吐槽一句,Vue的响应式有时候就是这么矫情,改个数组还得整个新引用才行。拿去试试吧,应该没问题了。
父组件这样写:
子组件这样写:
模板里记得加上事件监听:
<child :products="cartList" @add="addItem" />用展开运算符
[...]创建新数组最省事,Vue能检测到变化自动更新视图,不用手动调this.$forceUpdate。