5

vue中组件熟练使用非常重要,组件间通信的方式主要包括:父——》子;子——》父;非父子之间通信。

组件间的关系

将组件组合在一起,多数场景是父子关系:组件 A 可以在自己的模板中使用组件 B。这就必然的需要彼此相互通信:父组件可能会向下传递数组给子组件,然后子组件也可能会将自身发生的变化通知到父组件。然而,重要的是,为了尽可能将父子组件解耦,需要有一个定义清晰的接口。定义清晰的通信方式,可以确保组件可以相对隔离地组织代码,以及合乎逻辑易于推断,从而使它们更加易于维护,并且可能更加易于复用。

在 Vue 中,父子组件之间的关系可以概述为:props 向下,events 向上。父组件通过 props 向下传递数据给子组件,子组件通过 events 发送消息给父组件。

clipboard.png

父——》子

父组件向子组件传递数据通过Props

每个组件实例都有自己的孤立作用域。不能直接在子组件模板中引用父组件数据。要想在子组件模板中引用父组件数据,可以使用props将数据向下传递至子组件。
例如:

父组件:

<parent>
    <child v-bind="child-msg"></child>//这里必须要用 - 代替驼峰
</parent>

data(){
    return {
        msg: [1,2,3]
    };
}

子组件通过props来接收数据:

方式1:

props: ['childMsg']

方式2:

props: {
    childMsg: Array //这样可以指定传入的类型,如果类型不对,会警告
}

方式3

props: {
    childMsg: {
        type: Array,
        default: [0,0,0] //这样可以指定默认的值
    }
}

这样,就实现了父组件向子组件传递数据。
注意:子组件接收到的数据,不要修改,官方定义的props是单向绑定。如果需要修改,可以将接收到的值赋给data里面的一个变量,这样,就不会造成父组件里面的数据被篡改。
总结下:

总结下:

父组件中import子组件,并注册
父组件调用子组件,并绑定需要传值的属性值
子组件zhong

子——》父

子组件向父组件传递数据通过$on和$emit
子组件是通过点击事件去传递参数的。

vm.$emit( event, […args] ) 触发当前实例上的事件,附加参数会传给监听器回调。

在子组件中添加一个click事件,该事件通过this.$emit将方法或属性传递给父组件,其中第一个参数表示会触发父组件上的方法,后面的参数为向父组件传递的数据。

子组件:
<template>
    <div @click="up"></div>
</template>

methods: {
    up() {
        this.$emit('upup','hehe'); //主动触发upup方法,'hehe'为向父组件传递的数据
    }
}

父组件中就可以监听子组件传过来的属性。
父组件通过监听upup方法,可以获取子组件传递的数据。下面例子中,change方法里面的参数表示的就是从子组件传递过来的数据。

父组件:
<div>
    <child @upup="change" :msg="msg"></child> //监听子组件触发的upup事件,然后调用change方法
</div>
methods: {
    change(msg) {
        this.msg = msg;
    }
}
总结下:
子组件需要以某种方式例如点击事件的方法来触发一个自定义事件
将需要传的值作为$emit的第二个参数,该值作为实参传给响应自定义事件的方法
在父组件中注册子组件并在子组件标签上绑定对自定义事件的监听
在通信中,无论是子组件向父组件传值还是父组件向子组件传值,他们都有一个共同点就是有中间介质,子向父的介质是自定义事件,父向子的介质是props中的属性。

非父子组件通信

非父子组件之间需要通过中央事件总线作为桥梁,来实现通信。
eventBus中只创建了一个新的Vue实例,以后它就承担起了组件之间通信的桥梁了,也就是中央事件总线,相当于中转站,用它来传递事件和接收事件。
例如:

  1. 创建中央事件总线

    import Vue from 'vue';
    export default new Vue;
  2. 组件1触发

    import bus from "../eventBus.js"; //引入中央事件总线
    <div @click="eve"></div>
    methods: {
        eve() {
            bus.$emit('change','hehe'); //bus触发事件
        }
    }

    我们在响应点击事件的eve函数中用$emit触发了一个自定义的change事件,并传递了一个字符串参数
    PS:$emit实例方法触发当前实例(这里的当前实例就是bus)上的事件,附加参数都会传给监听器回调。

  3. 组件2接收:

    import bus from "../eventBus.js"; //引入中央事件总线
    <div></div>
    mounted() {
        bus.$on('change', () => { //Hub接收事件
            this.msg = 'hehe';
        });
    }

    我们在mounted中,监听了change,并把传递过来的字符串参数传递给了$on监听器的回调函数
    PS:
    mounted:是一个Vue生命周期中的钩子函数,简单点说就类似于jquery的ready,Vue会在文档加载完毕后调 用mounted函数。
    $on:监听当前实例上的自定义事件(此处当前实例为bus)。事件可以由$emit触发,回调函数会接收所有传入事件触发函数($emit)的额外参数。

总结下:
1、 创建一个中央事件总线,例如eventBus,用它作为通信桥梁
2、在需要传值的组件中用bus.$emit触发一个自定义事件,并传递参数
3、在需要接收数据的组件中庸bus.$on监听自定义事件,并在回调函数中处理传递过来的参数。

对于更复杂的组件状态管理,vue提供了vuex(状态管理模式)来进行处理。


Daisy
95 声望5 粉丝