应该说在学习vue的过程中,组件通信是相当重要的吧;这里有几种通信的方法;
通信:包含传参,控制(A操控B做一件事)、数据共享
1. 父组件可以将一条数据传递给子组件,这条数据可以是动态的,父组件的数据更改的时候,子组件接收的也会变化;
子组件被动的接收父组件的数据,子组件不要再更改这条数据了
<div id="app"> <father></father> </div> <template id="father"> <div> <p>父组件:</p> <input type="text" v-model="msg"/> <hr> <son :father-msg="msg"></son> </div> </template> <template id="son"> <div> <p>子组件:</p> <input type="text" v-model="fatherMsg"/> <p>这是父组件的数据:{{fatherMsg}}</p> </div> </template> </body> <script src="./base/vue.js"></script> <script> //要将子组件写在前面 Vue.component("son",{//注册子组件 template:"#son", props:['fatherMsg'] }) Vue.component("father",{//注册父组件 template:"#father", data:function(){ return { msg:'hello world' } } }) new Vue({ el:"#app" }) </script>
2. 父组件如果将一个引用类型的动态数据传递给子组价的时候,数据会变成双向控制的,子组件改数据的时候父组件也能接收到数据变化,因为子组件改的时候不是在改数据,而是在改数据里的内容,也就是说引用类型数据的地址始终没有变化,不算改父组件数据
父子间数据共享(双向控制)
<body> <div id="app"> <father></father> </div> <template id="father"> <div> //父组件作用域 <p>父组件:</p> <input type="text" v-model="msg.text"> <hr> <son v-bind:msg="msg" ></son> </div> </template> <template id="son"> <div>//子组件作用域 <p>子组件:</p> <input type="text" v-model="msg.text"> <p>msg:{{msg.text}}</p> </div> </template> </body> <script src="./base/vue.js"></script> <script> Vue.component("son",{ template:"#son", props:['msg'] //接收父组件传递的数据 }) Vue.component("father",{ template:"#father", data:function(){ return { msg:{//写成对象的形式 text:'hello world' } } } }) new Vue({ //创建的实例 el:"#app" }) </script>
3. 父组件可以将一个方法传递给子组件,子组件调用这个方法的时候,就可以给父组件传递数据
父组件被动的接收子组件的数据
<body> <div id="app"> <father></father> </div> <template id="father"> <div> <p :style="{color:color}">父组件:</p>
//传递方法给子组件 <son :change-color = "changeColor"></son> </div> </template> <template id="son"> <div> <p>子组件:</p> <button @click="changeColor('red')">red</button> //点击事件 <button @click="changeColor('blue')">blue</button> </div> </template> </body> <script src="./base/vue.js"></script> <script> Vue.component("son",{ template:"#son", props:['changeColor'] //子组件接收该方法 }) Vue.component("father",{ template:"#father", data:function(){ return { color:'' } }, methods:{//父组件的方法 changeColor(color){//更改data里的数据 this.color = color } } }) new Vue({ el:"#app" }) </script>
4. 父组件可以将一个事件绑定在子组件的身上,这个事件的处理程序是父组件某一个方法,当子组件触发自己的这个被绑定的事件的时候,相当于触发了父组件的方法;父组件被动的接收子组件的数据
<div id="app"> <father></father> </div> <template id="father"> <div> <p :style="{color:color}">父组件:</p> <son @change-color="changeColor"></son> </div> </template> <template id="son"> <div> <p>子组件:</p> <button @click="emitChangeColor('red')">red</button> <button @click="emitChangeColor('blue')">blue</button> </div> </template> </body> <script src="./base/vue.js"></script> <script> Vue.component("son",{ template:"#son", methods:{ emitChangeColor(color){//子组件点击事件触发changeColor方法,相当于触发父组件的方法 this.$emit('change-color1',color) } } }) Vue.component("father",{ template:"#father", data:function(){ return { color:'yellow' } }, methods:{ changeColor:function(color){ this.color = color } } }) new Vue({ el:"#app" }) </script>
5. 在组件间可以用过ref形成ref链,组件还拥有一个关系链($parent,$children,$root),通过这两种链;理论来说,任意的两个组件都可以互相访问,互相进行通信;任意组件通信,用的少...
<body> <div id="app"> <father></father> </div> <template id="father"> <div> <p>父组件:</p> <button @click=" controlSon('red')">red</button> //父组件绑定点击事件;触发子组件的方法 <button @click=" controlSon('blue')">blue</button> <hr> <son ref="son"></son> </div> </template> <template id="son"> <div> <p :style="{color:color}">子组件:</p> </div> </template> </body> <script src="./base/vue.js"></script> <script> Vue.component("son",{//子组件 template:"#son", data:function(){ return { color:'' } }, methods:{ doSomething:function(color){ this.color = color; alert(1) } } }) Vue.component("father",{ template:"#father", data:function(){ return { } }, methods:{ controlSon:function(color){ //调用子组件的doSomething方法就可以了 this.$refs.son.doSomething(color) } } }) new Vue({ el:"#app" }) </script>
6. event bus 事件总线 小天使 专注于非父子组件的通信,其实父子组件也可以使用,只是没有必要在B组件的某个钩子函数为event_bus绑定一个事件,事件的处理程序是B想做的事情;在A组件的某一个操作里,触发event_bus绑定的事件
<style> .box{ width: 200px;height: 200px; background: rgb(23, 177, 224); display: flex;justify-content: center;align-items: center; } </style> <body> <div id="app"> <aaa></aaa> <hr> <bbb></bbb> </div> <template id="aaa"> <div :style="{background:color}" class="box"> <button @click="changeBColor">change</button>//触发aaa的点击事件 </div> </template> <template id="bbb"> <div :style="{background:color}" class="box"> <button @click="changeAColor">change</button> </div> </template> </body> <script src="./base/vue.js"></script> <script> //事件总线实例 var angel = new Vue({ var mixin = {//公共样式,全局 methods:{ changeColor:function(){ var rand1 = Math.floor(Math.random()*256) var rand2 = Math.floor(Math.random()*256) var rand3 = Math.floor(Math.random()*256) this.color = `rgb(${rand1},${rand2},${rand3})` } } } Vue.component("aaa",{ template:"#aaa", data:function(){return {color:'rgb(23, 177, 224)'}}, mixins:[mixin], methods:{ changeBColor(){ //父组件触发绑定在小天使上的方法 //调用B组件的changeColor方法 //触发小天使的事件 angel.$emit("change-b-color") } }, mounted(){//挂载数据 angel.$on("change-a-color",this.changeColor) } }) Vue.component("bbb",{ template:"#bbb", data:function(){return {color:'rgb(23, 177, 224)'}}, mixins:[mixin], methods:{ changeAColor(){ //调用B组件的changeColor方法 //触发小天使的事件 angel.$emit('change-a-color') } }, mounted(){ //给小天使绑事件 let that = this angel.$on('change-b-color',function () {//挂载在angel的方法 that.changeColor() }) } }) new Vue({ el:"#app" }) </script>
7. 大量组件间数据共享的时候 vuex