【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之后,我们可以看到如下的结果:

【Vue】vue2.0中,子组件修改父组件传递过来得props,该怎么解决?

我们在子组件的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

回到顶部