使用vue的.sync,子组件修改同步父组件数据时报错:Avoid mutating a prop directly since...

674 阅读1分钟

问题描述:

使用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,并将其反映到父组件的模板中。