【Vue】vue2.0中,子组件修改父组件传递过来得props,该怎么解决?
vue2.0中,子组件中不能修改父组件的状态,否则在控制台中会报错。
但是经我测试发现,这仅限于props为非数组及对象等引用类型数据,譬如字符串,数字等
如果props是对象的话,在子组件内修改props的话,父组件是不会报错的。
测试代码如下:
parent.vue
<template><div class="">
<p>parent</p>
<child :test="test"></child>
<p>这是父组件中的data:{{test.hello}}</p>
</div>
</template>
<script type="text/ecmascript-6">
import Child from './child.vue'
export default {
data() {
return {
test: {
hello: 1
}
}
},
components: {
Child
}
}
</script>
<style>
</style>
child.vue
<template><div class="">
<p>child</p>
<p>这是子组件中的props:{{test.hello}}</p>
<input type="text" v-model="test.hello">
<p></p>
</div>
</template>
<script type="text/ecmascript-6">
export default {
props:{
test: {
type:Object
}
}
}
</script>
<style>
</style>
运行parent.vue之后,我们可以看到如下的结果:
我们在子组件的input中,直接绑定到props上,这样,我们修改input的内容,会发现,子组件的props被修改了,同时,父组件的data一样也被修改了,更关键的是,我们打开控制台,可以看到。没有报错。
这是不是违背了作者的子组件不修改props的意图?或者说,如果是传递的props的话,是不是就可以在子组件中修改props,从而达到修改父组件data的目的?但是结果就如作者所说,会导致父组件的data混乱,而且难以捕捉。请问,遇到这种情况,该怎么有效而又可靠的解决掉?
回答
如果非得需要修改传入的prop为对象的属性,而又不想破坏原对象,可以考虑深拷贝一下这个对象。
ES6提供的Object.assign({}, prop)的返回值就是一个全新的对象,操作这个新对象不会影响旧对象。如果不用ES6就自己递归实现拷贝器
1.给computed属性设置get和set方法,并利用Object.assign()浅克隆或者JSON.stringify()深度拷贝对象可以完美解决修改props传值问题,贴上代码段
computed:{ dialogFormVisible:{
get:function(){
return this.addData=Object.assign({},this.dialogEditOrAddData)
},
set:function(newValue){
return this.addData=newValue
}
}
},
2.另外建议如果要修改props传入的值,用watch可以多次修改,watch监听对象得用深度监听贴上代码
watch:{ dialogEditOrAddData:{//dialogEditOrAddData得在data中声明
handler(oldVal,newVal){
this.dialogFormVisible=newVal
},
deep:true
}
},
3.computed修改的值虽然get时是深度克隆对象,但是set时还是会修改父组件的值,所以如果是子组件修改后的值和父组件设置方法的值一致,第二次computed就不会触发拉
文档中写的很清晰,prop
是单向数据流的,原则上子组件修改props是不被允许,或许你可以去给vue 提 issue
.
另外,子组件修改prop文档中给的方法是使用自定义事件回调函数完成的.文档链接:
https://cn.vuejs.org/v2/guide/components.html#使用-v-on-绑定自定义事件
首先,组件间的数据传递只能是父到子,数据流向的单一保证了数据变化的可追踪性;如果子组件操作该值要求父组件作出相应变化时,那就子组件emit一个事件,父组件内捕获这个事件,然后在父组件内执行相应的变化;如果只是想通过props获取一个初始值,之后无论子组件如何操作该值都不会影响父组件的变化,那就在传入子组件数据的时候就进行一下处理(值引用类型数据无需处理,址引用数据进行一下深度拷贝Object.assign({},obj)或者JSON.parse(JSON.stringify(obj)))
尤大不反对这种方式,可以作为一个父子组件间双向通信的简易方案。
子组件修改父组件的prop,虽然报warning但也是可以成功运行的。
如果你想实现双向传递,首先考虑v-model,再考虑自定义事件。v-model仅仅是一个语法糖,他内部还是自定义事件。
如果你不想,那么设置temp变量,缓存prop过来的数据,再操作temp即可。
不是有computed么
可以使用 自定义组件的 v-model
对象和数组都是引用传递,字符串数字属于值传递
process.env.NODE_ENV !== 'production'的时候就会出现警告,你没设置process.env.NODE_ENV吧
以上是 【Vue】vue2.0中,子组件修改父组件传递过来得props,该怎么解决? 的全部内容, 来源链接: utcz.com/a/71652.html