美文网首页
组件之间的通信

组件之间的通信

作者: 谢_ffd1 | 来源:发表于2019-03-20 18:58 被阅读0次

    简单提要

    组件通信主要方式有四种:
    1.通过prop进行组件之间的单向通讯(父子组件之间的单向通讯)=>特点:

    父组件值改变,子组件相应改变.但子组件改变不影响父组件

    <div style="color: red;margin-top: 15px">正常父子组件(单向)通讯: 父组件值改变,子组件相应改变.但子组件改变不影响父组件</div>
    <div id="parent">
    <span>父组件</span>
    <input type="text" v-model="parentMessage">
    <br>
    <child :message="parentMessage"></child>
    </div>
    <script>
        Vue.component('child', {
            props: ['message'],
            template: `<div>
                <span>子组件</span>
                <input type="text" v-model="message">
                </div>`,
        });
        new Vue({
            el: '#parent',
            data: {
                parentMessage: 'hello, child!'
            }
        });
    </script>
    

    2.通过组件的自定义事件进行组件之间的单向通讯(子父组件之间的单向通讯)=>特点

    子组件值改变,父组件相应改变.但父组件改变不影响子组件

    <div style="color: red;margin-top: 15px">子父组件单向通讯: 子组件通过触发父组件事件改变父组件的值</div>
    <div id="parent3">
        <span>父组件</span>
        <input type="text" v-model="parentMessage">
        <br>
        <!---注意下面这行用的是.sync修饰符--->
        <child3 @update:message="parentMessage2"></child3>
    </div>
    <script>
    Vue.component('child3', {
            data(){
                return{
                    message:'hello, parent!'
                }
            },
            template: `<div>
                <span>子组件</span>
                <input type="text" v-model="message">
                </div>`,
            watch: {
                message:function () {
                    this.$emit('update:message', this.message);
                }
            },
            mounted(){
                this.$emit('update:message', this.message);
            }
        });
    
        new Vue({
            el: '#parent3',
            data: {
                parentMessage: 'hello!'
            },
            methods: {
                parentMessage2(msg) {
                    this.parentMessage = msg;
                }
            }
        });
    </script>
    

    3.通过组件的自定义事件进行组件之间的(双向)通讯=>特点

    (利用prop特性)子组件通过触发父组件事件改变其自身的值从而改变子组件的值

    <div style="color: red;margin-top: 15px">正常子父组件(双向)通讯(不使用.sync修饰符): (利用prop特性)子组件通过触发父组件事件改变其自身的值从而改变子组件的值</div>
    <div id="parent2">
        <span>父组件</span>
        <input type="text" v-model="parentMessage">
        <br>
        <child2 :message="parentMessage" @update:message="parentMessage2"></child2>
    </div>
    <script>
        Vue.component('child2', {
            props: ['message'],
            template: `<div>
                <span>子组件</span>
                <input type="text" v-model="message">
                </div>`,
            watch: {
                message: function () {    
                    this.$emit('update:message', this.message);
                }
            }
        });
    
        new Vue({
            el: '#parent2',
            data: {
                parentMessage: 'hello, child!'
            },
            methods: {
                parentMessage2(msg) {
                    this.parentMessage = msg;
                }
            }
        });
    </script>
    
    

    关于该类方法实现的组件之间的双向通信,官方提供了一种 .sync 修饰符来简化实现

    <div style="color: red;margin-top: 15px">正常子父组件(双向)通讯(使用.sync修饰符): (利用prop特性)子组件通过触发父组件事件改变其自身的值从而改变子组件的值</div>
    <div>使用使用.sync修饰符的好处是:省略在父组件上给子组件添加监听方法,且也省略了实现该方法的主体。在子组件中直接使用 this.$emit('update:value', this.value)  value为子组件中的props的key  来触发父组件值得改变同时响应子组件的值一起改变(说白了就是遵循prop单向数据流规则)</div>
    <div id="parent5">
        <span>父组件</span>
        <input type="text" v-model="parentMessage">
        <br>
        <!---注意下面这行用的是.sync修饰符--->
        <child5 :message.sync="parentMessage"></child5>
    </div>
    <script>
       Vue.component('child5', {
            props: ['message'],
            template: `<div>
                <span>子组件</span>
                <input type="text" v-model="message">
                </div>`,
            watch: {
                message: function () {           
                    this.$emit('update:message', this.message);
                }
            }
        });
    
        new Vue({
            el: '#parent5',
            data: {
                parentMessage: 'hello, child!'
            },
            methods: {
    
            }
        });
    </script>
    

    使用使用.sync修饰符的好处是:省略在父组件上给子组件添加监听方法,且也省略了实现该方法的主体。在子组件中直接使用 this.$emit('update:value', this.value) value为子组件中的props的key 来触发父组件值得改变同时响应子组件的值一起改变

    4.通过vue事件总线进行组件之间的(双向或单向)通讯=>特点

    <div style="color: red;margin-top: 15px">vue事件总线</div>
    <div id="parent4">
        <span>父组件</span>
        <input type="text" v-model="parentMessage">
        <br>
        <child4></child4>
    </div>
    
    <script>
     var relay = new  Vue();
    
        Vue.component('child4', {
            data(){
                return{
                    message:'hello, parent!'
                }
            },
            watch:{
                message(){
                    relay.$emit("parent",{message:this.message})
                }
            },
            template: `<div>
                <span>子组件</span>
                <input type="text" v-model="message">
                </div>`,
            mounted() {
                relay.$on("child",(options)=>{
                    this.message=options.parentMessage;
                });
                relay.$emit("parent",{message:this.message})
            }
        });
    
        new Vue({
            el: '#parent4',
            data: {
                parentMessage: 'hello, child!'
            },
            watch:{
                parentMessage(){
                    relay.$emit("child",{parentMessage:this.parentMessage})
                }
            },
            mounted() {
                relay.$on("parent",(options)=>{
                    this.parentMessage=options.message;
                });
                relay.$emit("child",{parentMessage:this.parentMessage})
            }
        });
    </script>
    

    当然这四种是比较常用的 实现组件通信还可以使用:
    处理边界情况

    • 通过$parent属性访问父组件
    • 通过children属性访问子组件
    • 给组件命名,通过指定名称来访问
    <base-input ref="usernameInput"></base-input >
    this.$refs.usernameInput
    
    • 等等 ····

    相关文章

      网友评论

          本文标题:组件之间的通信

          本文链接:https://www.haomeiwen.com/subject/dzrnmqtx.html