问题描述:
使用vue的.sync实现父子组件数据双向绑定时,子组件修改同步父组件数据时报错:Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders.
原因描述
当你在子组件中使用 v-model 和 .sync 修饰符时,实际上是将子组件的属性和方法传递给父组件。 因此,如果你在子组件中修改了传递给它的 prop,它实际上就是在尝试修改父组件中的数据,这是不被允许的。 因为Vue的单向数据流规则要求子组件不能直接修改从父组件传递下来的 prop。 相反,它们应该通过触发事件或调用回调函数来告诉父组件何时更改。
在这种情况下,你应该将 prop 的值绑定到一个本地的 data 属性中,然后在子组件中修改本地的 data 属性。如果你需要将更改后的值传递回父组件,则可以使用 $emit 方法触发一个自定义事件,并将更改后的值作为参数传递。
以下是一个示例代码,展示了如何正确地使用 v-model 和 .sync 修饰符:
<!-- 父组件 -->
<template>
<div>
<div>父组件:</div>
<input type="text" v-model="localData" />
<ChildComponent :propName.sync="localData"></ChildComponent>
</div>
</template>
<script>
import ChildComponent from "./components/HelloWorld.vue";
export default {
components: { ChildComponent },
data() {
return {
localData: ""
};
}
};
</script>
<!-- 子组件 -->
<template>
<div>
<div>子组件:</div>
<input type="text" v-model="localProp" />
</div>
</template>
<script>
export default {
props: ["propName"],
computed: {
localProp: {
get() {
return this.propName;
},
set(value) {
this.$emit("update:propName", value);
}
}
}
};
</script>
总结
在这个示例中,父组件将 localData 作为 propName 传递给子组件,并通过 v-model 和 .sync 修饰符绑定了子组件的 localProp 计算属性。当子组件中的 localProp 改变时,它会通过 $emit 方法触发一个名为 update:propName 的自定义事件,并将更改后的值作为参数传递。这会更新父组件中的 localData,并将其反映到父组件的模板中。