vue中组件熟练使用非常重要,组件间通信的方式主要包括:父——》子;子——》父;非父子之间通信。
组件间的关系
将组件组合在一起,多数场景是父子关系:组件 A 可以在自己的模板中使用组件 B。这就必然的需要彼此相互通信:父组件可能会向下传递数组给子组件,然后子组件也可能会将自身发生的变化通知到父组件。然而,重要的是,为了尽可能将父子组件解耦,需要有一个定义清晰的接口。定义清晰的通信方式,可以确保组件可以相对隔离地组织代码,以及合乎逻辑易于推断,从而使它们更加易于维护,并且可能更加易于复用。
在 Vue 中,父子组件之间的关系可以概述为:props 向下,events 向上。父组件通过 props 向下传递数据给子组件,子组件通过 events 发送消息给父组件。
父——》子
父组件向子组件传递数据通过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实例,以后它就承担起了组件之间通信的桥梁了,也就是中央事件总线,相当于中转站,用它来传递事件和接收事件。
例如:
-
创建中央事件总线
import Vue from 'vue'; export default new Vue;
-
组件1触发
import bus from "../eventBus.js"; //引入中央事件总线 <div @click="eve"></div> methods: { eve() { bus.$emit('change','hehe'); //bus触发事件 } }
我们在响应点击事件的eve函数中用$emit触发了一个自定义的change事件,并传递了一个字符串参数
PS:$emit实例方法触发当前实例(这里的当前实例就是bus)上的事件,附加参数都会传给监听器回调。 -
组件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(状态管理模式)来进行处理。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。