小程序中如何让子组件修改父组件传递的数组数据?

Mr.爱霖 阅读 12

大家好,我在做一个购物车小程序,父组件通过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?

我来解答 赞 3 收藏
二维码
手机扫码查看
2 条解答
Mc.玲玲
Mc.玲玲 Lv1
你这问题出在两个地方,一个是直接修改了prop,另一个是父组件没正确更新数据。Vue的prop是单向数据流,不能直接改,你得通过事件通知父组件来更新。

先说子组件,别直接动 this.products,只管发事件出去就行:

export default {
props: ['products'],
methods: {
addToCart() {
const newItem = { id: 1, name: '测试品' }
this.$emit('add', newItem) // 只负责通知父组件
}
}
}


然后父组件这边,你得确保正确监听事件并且更新自己的数据。直接改你原来的代码,拿去改改:

<template>
<div>
<child :products="cartList" @add="addItem"></child>
</div>
</template>

<script>
export default {
data() {
return {
cartList: [] // 初始购物车列表
}
},
methods: {
addItem(newProduct) {
this.cartList = [...this.cartList, newProduct] // 用新数组触发响应式更新
}
}
}
</script>


关键点是父组件不要直接 push,而是用扩展运算符 [...] 创建一个新数组,这样能确保Vue的响应式系统检测到变化并更新页面。至于 $forceUpdate,根本不用,那是绕开Vue正常机制的下策。

另外吐槽一句,Vue的响应式有时候就是这么矫情,改个数组还得整个新引用才行。拿去试试吧,应该没问题了。
点赞 2
2026-02-16 22:08
开发者馨然
问题出在你直接改了prop传的数组,Vue里prop是单向数据流,不能直接改。省事的话,父组件监听事件后自己改数据,子组件只负责通知。

父组件这样写:
export default {
data() {
return {
cartList: []
}
},
methods: {
addItem(newProduct) {
this.cartList = [...this.cartList, newProduct]
}
}
}


子组件这样写:
export default {
props: ['products'],
methods: {
addToCart() {
const newItem = { id: 1, name: '测试品' }
this.$emit('add', newItem)
}
}
}


模板里记得加上事件监听:<child :products="cartList" @add="addItem" />

用展开运算符[...]创建新数组最省事,Vue能检测到变化自动更新视图,不用手动调this.$forceUpdate
点赞 1
2026-02-16 08:04