首先来看看最后一种通信方式,假如我们有一个输入框,让用户填写优惠码,填完之后在组件里面进行判断,然后返回结果给实例,基本实现如下。

首先定义一个优惠券:

<div id="root" class="container">
    <coupon></coupon>
</div>

<script type="text/javascript">
    
    Vue.component('coupon', {
        template:`
            <input type="text" />
        `
    });

    var vm = new Vue({

        el:"#root"

    });

</script>

用户输完优惠码之后,触发 blur 事件,绑定到 onCouponApplied 方法,在方法里面可以对优惠码进行应用,比如判断是否过期等等,应用完之后需要把结果返回给实例:(这里忽视具体的应用过程)

Vue.component('coupon', {
    template:`
        <input type="text"  @blur="onCouponApplied" />
    `,
    methods: {
        onCouponApplied() {
            // 应用该优惠码,省略
            // 触发事件
            this.$emit('applied');
        }
    }
});

然后是父组件监听该事件,作出响应:

<div id="root" class="container">
    <coupon @applied="onCouponApplied"></coupon>
    <h1 v-if="couponApplied">该优惠码已应用!</h1>
</div>

<script type="text/javascript">
    
    var vm = new Vue({

        el:"#root",
        methods: {
            onCouponApplied(){
                this.couponApplied = true;
            }
        },
        data: {
            couponApplied:false
        }

    });

</script>

这种情形其实就是之前我们所说的组件的内部通信,组件传递数据给实例,使用 $emitv-on。当然,我们还有一种更简便的实现方法:

window.Event = new Vue(); // 创建一个全局变量 Event,绑定到 Vue 实例
Vue.component('coupon', {
    template:`
        <input type="text"  @blur="onCouponApplied" />
    `,
    methods: {
        onCouponApplied() {
            Event.$emit('applied'); // 实例触发 `applied` 事件
        }
    }
});

var vm = new Vue({

    el:"#root",
    methods: {
        onCouponApplied(){
            this.couponApplied = true;
        }
    },
    data: {
        couponApplied:false
    },
    created(){
        Event.$on('applied',function(){ // 实例监听 `applied` 事件
            vm.couponApplied = true
        })
    }

});

可以看出,我们定义了一个全局的公共实例,用于作为事件触发和监听的桥梁。使用这种方法的话,不同组件之间也可以进行通信。

最后,我们来总结下目前为止学到过的组件之间的通信方式吧:

  • 组件的内部通信:

    • 实例传数据给组件:props

    • 组件反传数据给实例:$emit 以及 v-on

  • 在一个组件中使用另外一个组件:

    • 父组件可使用 $children 来访问子组件

    • 子组件可以使用 $parent 来访问父组件

  • 不同组件之间的通信:通过定义公共实例作为桥梁,使用 $emit$on 触发和监听事件

  • 属性传递

    • 静态的 - 传递字面量

    • 动态的 - 传递表达式


心智极客
1k 声望645 粉丝