vue 里组件的通信

应该说在学习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
原文地址:https://www.cnblogs.com/naniandongzhi/p/8119981.html