【发布时间】:2021-11-19 01:32:26
【问题描述】:
我的组件数据中有一个对象。现在,我只是使用v-bind.sync 指令将对象的所有属性作为道具绑定到子组件。我正在使用内置的update 事件从子组件更新这些道具,但我仍然在控制台中收到Avoid mutation props directly 错误。这是附加的最小示例。
父组件
<template>
<div>
<oslo v-bind.sync="data" />
</div>
</template>
<script>
import Oslo from '@/components/Oslo.vue'
export default {
components: {
Oslo,
},
name: 'OsloParent',
data() {
return {
data: {
data: {
name: 'Oslo name',
access: 'admin'
}
},
}
},
}
</script>
子组件
<template>
<div>
<input type="text" v-model="name" @keyup="$emit('update:name', name)" />
<input type="text" v-model="access" @keyup="$emit('update:access', access)" />
</div>
</template>
<script>
export default {
props: {
name: String,
access: String
},
name: 'Oslo',
}
</script>
这只是我为重现问题而创建的示例组件。实际的组件应该通过双向绑定处理这么多道具,这就是我使用 v-bind 指令和 sync 修饰符绑定数据的原因。这是来自控制台的 Vue 警告(最常见)。
[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "name"
有什么建议可以改进这一点或让 Vue 针对这种特定情况发出警告?上面给出的组件可以正常工作,但是 Vue 会抛出错误。
【问题讨论】:
-
从docs 我了解到,如果您在此之前使用
.sync而没有明确的属性,它会假定一个对象。所以$emit应该设置/更新整个对象,而不仅仅是它的一个属性。您可以在子组件上拥有一个计算属性,该属性收集当前属性值和$emits 整个对象。 -
如果您可以在您的问题中制作一个小型工作示例作为 sn-p,我可以看看您如何做到这一点。
-
您也将组件导入为
Properties,但使用Oslo。所以也许引用是错误的? -
对于导入,实际组件很复杂,我实际上是在这里写代码,所以只是一个错字(已更正)。对于第一条评论,上面给出的两个父子组件都完美地更新了值。我在 devtools 中检查过。
-
您可以尝试将
v-model更改为v-bind:name以使其将属性显示为输入值,但属性的更新仅通过$emit事件进行。还可以查看the docs 的示例。
标签: vue.js vuejs2 two-way-binding vue-directives