父子组件之间的通信
- 关于父子之间的通信问题,最常用的就是 props 和 provide/inject,子组件使用父组件传递过来的数据,进行视图的渲染,而实际开发中我们使用父子组件通信的时候,往往会在子组件中对父组件传递过来的数据进行修改和补充,相信对以下控制台的报错信息都不会陌生把:
- 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: "aaa"
- Avoid mutating an injected value directly since the changes will be overwritten whenever the provided component re-renders. injection being mutated: "cc"
- 以上第一句是通过 props 获取数据后,在子组件中修改数据之后控制台的报错信息,第二句是 通过 provide/inject 获取到数据之后,修改数据时控制台的报错信息;
js 引用
- js 复杂数据类型(Object、Array、Date、Function 等)在存储时变量中存储的仅仅是地址(引用);
- 而我们调用该数据时,拿到的也仅仅是一个地址(引用);
将父子组件通信和引用联系起来
-
上文说到父子组件之间的通信,子组件对父组件传递过来的数据进行修改和补充时,控制台会有报错信息,但是我们可不可以修改获取到的数据而程序不认为我们修改了数据呢(我修改了,但又没修改);
-
结合 js 复杂数据类型中的引用来说,这是完全可以实现的,也就是说我们将父子组件之间传递引用时,只要我们不对此引用进行修改,程序就不会认为我们修改了这条数据;
// 父组件 <template> <div> 父组件 aaa:{{aaa}},== a:{{a}} <test :aaa="aaa" /> </div> </template> <script> import test from './compoent/test.vue' export default { components: { test }, name: 'showExcel', data () { return { // 定义一个对象,这里有一个小技巧,后面会讲到 a: { b: 123 }, aaa: { a: '123456' }, } }, provide () { return { a: this.a } }, } </script> // 子组件 <template> <div> 子组件中 aaa:{{aaa}},== a:{{a}} </div> </template> <script> export default { name: 'test', inject: ['a',], props: { aaa: Object, }, mounted () { setTimeout(() => { this.aaa.a = '000111' this.a.b = '000222' }, 3000); }, } </script>
-
数据修改之前效果图
数据修改之前
-
数据修改之后效果图
数据修改之后
-
以上代码中我们使用到了引用,而我们常用到的复杂数据类型中还有 Array,对于数组的操作本质上也是一样,只要子组件不改变数组的引用即可,并且在改变数据的同时,要让视图也一起刷新的话,需要使用到数组的以下 7 个方法:push、pop、shift、unshift、splice、sort、reverse,因为 vue 框架中对数组的这 7 个方法进行了重写,在调用这 7 个方法的同时会触发视图更新;
Vue组件通信—provide/inject
网友评论