前言
报错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: “status” 父组件通过props传值给子组件,如何解决因为在子组件改变props传来的值导致的报错呢?一、官方文档:
在vue关于props的文档中,父子组件中的数据流是单向的,为什么是单向的呢,其实这是比较合理的,要是双向的话,当我们某个子组件对父组件的值进行了操作,就会导致这个父组件下的所有子组件的值都发生改变,所以文档中给出了下面子组件操作数据时的解决方法。
二·、具体的解决方法实现:
从组件信息的单向流动,我们知道报错的原因了,但是我们在使用中确实需要对这个父组件传来的值进行更改的话,需要如何实现呢?
- 第一步:在子组件中接收到父组件的值
props: {
searchKey: {
type: String,
default: null
},
stateCategory: {
type: String,
default: null
}
},
- 第二步:在子组件中创建新的局部变量,并且把从父组件获取到的值赋给新的变量
data(){
return {
searchWord: this.searchKey,
stateCategoryValue: this.stateCategory,
},
- 第三步:创建监听,只要父组件传来的值发生变更就重新赋值给子组件的局部变量,同时创建子组件和父组件的联系,用来把子组件更新的值同步到父组件
watch: {
searchKey(value) {
this.searchWord = value;
},
searchWord(value) {
this.$emit('update:searchKey', value);
},
stateCategory(value) {
this.stateCategoryValue = value;
},
stateCategoryValue(value) {
this.$emit('update:stateCategory', value);
}
},
- 第四步:到这里就大功告成了,我们可以使用我们创建的局部变量,同时保证我们需要的效果
<el-input
v-model="searchWord"
v-trim="searchWord"
/>
<el-select
v-model="stateCategoryValue"
v-trim="stateCategoryValue"
/>
这里补充一点:
要是我们的值是对象的话,就不能直接赋值了,需要用到深拷贝来获取到,众所周知,对象的话赋值只是把在栈里面的引用地址赋值给它,实际数据是存在堆内存的。
总结
vue的论坛里有讨论过这个问题,一些别的解决方法可以去了解一下,下次有空,我也会尝试使用别的方法来实现效果。但是我们记住一句话:永远不要在子组件中修改父组件的数据!!