Vue 组件间通信只要指以下 3 类通信:
父子组件通信
隔代组件通信
兄弟组件通信
prop / $emit
prop/$emit适用 父子组件通信,这也是我们最常见用得最多的方法。
prop: 父组件通过在子组件上绑定参数,子组件通过 props 接收参数。
<!--父组件-->
:showMsg='参数'
<!--子组件-->
props: ['showMsg']
$emit: 子组件通过 $emit 派发自定义事件,由父组件监听事件,也可以进行参数的传递。
<!--子组件-->
this.$emit('自定义事件名字','参数')
<!--父组件-->
@自定义事件名字 = '事件名称'
事件名称 (val) {
return val
}
举个栗子:
我们在父组件上做两件事:
- 在子组件上绑定值
:fprops="msg" - 在子组件上接收自定义事件
@showMsg="updateMsg"
<!--父组件 parent.vue-->
<template>
<div>
<h2>Prop / $emit 传值</h2>
<h4>我是父组件</h4>
<div>接收子组件的参数: {{smsg}}</div>
<Child :fprops="msg" @showMsg="updateMsg"/>
</div>
</template>
<script>
import Child from './Child'
export default {
data () {
return {
// 定义 msg
msg: 'Hello Child',
smsg: ''
}
},
components: {
Child
},
methods: {
updateMsg (val) {
this.smsg = val
}
}
}
</script>
然后我们在子组件上,也做两件事:
- 通过 prop 接收父组件的传参
props: ['参数名'] - 通过
$emit派发自定义事件this.$emit('showMsg', 'Hello Parten')
<!--子组件-->
<template>
<div>
<h4>我是子组件</h4>
<div>接收父组件参数: {{fvalue}}</div>
<div @click="select"><button>给父组件传值</button></div>
</div>
</template>
<script>
export default {
props: {
fprops: {
type: String
}
},
data () {
return {
fvalue: this.fprops,
msg: 'Hello Parent'
}
},
methods: {
select () {
this.$emit('showMsg', 'Hello Parten')
}
}
}
</script>
$refs / $children / $parent
ref 如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素,如果用在子组件上,引用就指向组件实例。
例如将 ref 标记在子组件上:
<Child ref="myChild" />
然后父组件中就可以用过 this.$refs.myChild 访问这个子组件了,包括访问子组件的中data 里面的数据,或者调用它的函数。
$children 返回的是当前父组件下的所有子组件的集合,那到子组件的下标后,也是可以访问到子组件中的数据。
this.$children[子组件下标]
$parent 用在子组件身上,可以调用父组件中的数据和方法。
this.$parent
EventBus ($emit / $on)
EventBus 它的工作原理是发布/订阅方法 $emit 发布, $on 订阅.
EventBus 又称为事件总线.
初始化 EventBus
这里有两种方式,可以单独局部使用,需要的时候就引入,不需要的时候就不引用,或者直接定义成全局的。
- 局部
// 初始化 event-bus.js
import Vue from 'vue'
export const EventBus = new Vue()
- 全局
// main.js
var EventBus = new Vue()
Object.defineProperties(Vue.prototype, {
$bus: {
get: function () {
return EventBus
}
}
})
发布
通过 EventBus.$emit('EventBusName', '参数') 发布事件
- 局部
// 引用EventBus
import { EventBus } from '../../common/event-bus.js'
// 通过
EventBus.$emit('EventBusName', 'data')
- 全局
this.$bus.$emit('EventBusName', 'data')
订阅
通过 EventBus.$on 订阅事件
- 局部
EventBus.$on('EventBusName', (params) => {
//获取传递的参数并进行操作
})
- 全局
this.$bus.$on('EventBusName', (params) => {
//获取传递的参数并进行操作
})
移除 EventBus
vue是单页应用,如果你在某一个页面刷新了之后,与之相关的EventBus会被移除,这样就导致业务走不下去。
还要就是如果业务有反复操作的页面,EventBus 在监听的时候就会触发很多次,这也是不利于项目的优化。
通常会用到 EventBus.$off(),在vue页面 beforeDestory 阶段销毁前,移除EventBus 事件监听。
- 局部
<!--移除单个 EventBus-->
EventBus.$off('EventBusName')
<!--移除全部 EventBus-->
EventBus.$off()
- 全局
<!--移除单个 EventBus-->
this.$bus.$off('EventBusName')
<!--移除全部 EventBus-->
this.$bus.$off()
###