父子组件2.0
Posted yuyujuan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了父子组件2.0相关的知识,希望对你有一定的参考价值。
在前面总结过vue1.0中的组件通信,现在根据vue2.0的变化比较一下两者的不同之处。
首先还是用一个例子回顾一下之前的父子组件通信。
vue1.0
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue</title> <script src="vue1.0.js"></script> </head> <body> <template id="child"> <div> <span>我是子组件</span> <input type="button" value="按钮" @click="change"> <strong>{{msg}}</strong> </div> </template> <div id="box"> 父级: ->{{a}} <br> <child-com :msg="a"></child-com> </div> <script> new Vue({ el:‘#box‘, data:{ a:‘我是父组件数据‘ }, components:{ ‘child-com‘:{ props:[‘msg‘], template:‘#child‘, methods:{ change(){ this.msg=‘被更改了‘ } } } } }); </script> </body> </html>
在上面的例子中,子组件是可以更改父组件的数据的,甚至可以通过添加sync实现同步修改,但是当我们把上面的js改为vue2.0的时候,会发现程序直接报错了。
这是因为在vue2.0中的prop中提出了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。额外的,每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。
针对子组件需要更改prop传过来的值,官方文档给出了两种办法。
本地data
第一种方法是这个prop用来传递一个初始值,当子组件希望将这个初始值用作一个本地数据使用时,最好定义一个本地的data属性并将这个prop用作其初始值。在下面的例子中,我们希望在子组件中使用父组件的数据a,首先在父组件中通过prop将这个数据传递到子组件,然后在子组件中定义一个b,这个b的初始值就是a,然后在子组件中对b进行操作。所以,此时只能更改b,并不能同步更改a。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue</title> <script src="vue.js"></script> </head> <body> <template id="child"> <div> <span>我是子组件</span> <input type="button" value="按钮" @click="change"> <strong>{{b}}</strong> </div> </template> <div id="box"> 父级: ->{{a}} <br> <child-com :msg="a"></child-com> </div> <script> new Vue({ el:‘#box‘, data:{ a:‘我是父组件数据‘ }, components:{ ‘child-com‘:{ props:[‘msg‘], data(){ return { b:this.msg } }, template:‘#child‘, methods:{ change(){ this.b=‘被更改了‘ } } } } }); </script> </body> </html>
官方中还提供了一种使用计算属性的方法。可以直接在官方查看,这里就不再演示了。
对象引用
除此之外,还有另外一种方法,那就是对象之间的引用,父组件不再是传递单一的基本类型数据给子组件,而是使用对象的形式进行传递,此时不仅能够实现子组件数据更改,还能同步更改父组件数据。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue</title> <script src="vue.js"></script> </head> <body> <template id="child"> <div> <span>我是子组件</span> <input type="button" value="按钮" @click="change"> <strong>{{msg.a}}</strong> </div> </template> <div id="box"> 父级: ->{{giveData.a}} <br> <child-com :msg="giveData"></child-com> </div> <script> new Vue({ el:‘#box‘, data:{ giveData:{ a:‘我是父组件数据‘ } }, components:{ ‘child-com‘:{ props:[‘msg‘], template:‘#child‘, methods:{ change(){ this.msg.a=‘被改了‘; } } } } }); </script> </body> </html>
单一事件管理组件通信。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue</title> <script src="vue.js"></script> </head> <body> <div id="box"> <com-a></com-a> <com-b></com-b> <com-c></com-c> </div> <script> //准备一个空的实例对象 var Event=new Vue(); var A={ template:` <div> <span>我是A组件</span> -> {{a}} <input type="button" value="把A数据给C" @click="send"> </div> `, methods:{ send(){ Event.$emit(‘a-msg‘,this.a); } }, data(){ return { a:‘我是a数据‘ } } }; var B={ template:` <div> <span>我是B组件</span> -> {{a}} <input type="button" value="把B数据给C" @click="send"> </div> `, methods:{ send(){ Event.$emit(‘b-msg‘,this.a); } }, data(){ return { a:‘我是b数据‘ } } }; var C={ template:` <div> <h3>我是C组件</h3> <span>接收过来的A的数据为: {{a}}</span> <br> <span>接收过来的B的数据为: {{b}}</span> </div> `, data(){ return { a:‘‘, b:‘‘ } }, mounted(){ //接收A组件的数据 Event.$on(‘a-msg‘,function(a){ this.a=a; }.bind(this)); //接收B组件的数据 Event.$on(‘b-msg‘,function(a){ this.b=a; }.bind(this)); } }; new Vue({ el:‘#box‘, components:{ ‘com-a‘:A, ‘com-b‘:B, ‘com-c‘:C } }); </script> </body> </html>
主要包括三个步骤:
-
准备一个空的实例对象 var Event=new Vue();
- 发送数据 Event.$emit(事件名称, 数据)
- 接收数据 Event.$on(事件名称,function(data){ }.bind(this));
以上是关于父子组件2.0的主要内容,如果未能解决你的问题,请参考以下文章