深入vue2.0源码系列: 事件机制的实现与运用
创始人
2025-05-28 21:42:22
0

前言

Vue.js 2.0使用了一种事件机制来实现组件间的通信和状态管理,本文将会介绍Vue.js 2.0事件机制的实现和运用。

事件机制的实现

Vue.js 2.0的事件机制实现依赖于一个名为 vm.$emit 的实例方法和一个名为 vm.$on 的实例方法。当组件需要向其他组件通信时,可以调用 vm.$emit 方法触发一个自定义事件,其他组件可以通过调用 vm.$on 方法来监听这个自定义事件。这样就能够实现组件间的通信。

下面我们来看一下 vm.$emitvm.$on 方法的实现。

vm.$emit 的实现

vm.$emit 方法定义在 src/core/instance/events.js 文件中,其实现如下:

// Vue实例原型上定义$emit方法
Vue.prototype.$emit = function (event: string): Component {const vm: Component = this// 开发环境下,如果事件名称存在大写字符并且存在监听该事件的回调函数,则输出警告if (process.env.NODE_ENV !== 'production') {const lowerCaseEvent = event.toLowerCase()if (lowerCaseEvent !== event && vm._events[lowerCaseEvent]) {warn(`Event "${lowerCaseEvent}" is emitted in component ` +`${formatComponentName(vm)} but the handler is registered for "${event}". ` +`Note that HTML attributes are case-insensitive and you cannot use ` +`v-on to listen to camelCase events when using in-DOM templates. ` +`You should probably use "${hyphenate(event)}" instead of "${event}".`)}}// 通过事件名称获取当前实例上所有监听该事件的回调函数let cbs = vm._events[event]if (cbs) {// 如果存在回调函数,则调用所有回调函数,并将参数传递给它们cbs = cbs.length > 1 ? toArray(cbs) : cbsconst args = toArray(arguments, 1)for (let i = 0, l = cbs.length; i < l; i++) {try {cbs[i].apply(vm, args)} catch (e) {handleError(e, vm, `event handler for "${event}"`)}}}return vm
}

vm.$on 的实现

vm.$on 方法的实现也定义在 src/core/instance/events.js 文件中,其实现如下:

Vue.prototype.$on = function (event: string | Array, fn: Function): Component {const vm: Component = thisif (Array.isArray(event)) {for (let i = 0, l = event.length; i < l; i++) {vm.$on(event[i], fn)}} else {// 如果不存在该事件的回调函数,则初始化一个空数组来存储(vm._events[event] || (vm._events[event] = [])).push(fn)// optimize hook:event cost by using a boolean flag marked at registration// instead of a hash lookupif (hookRE.test(event)) {vm._hasHookEvent = true}}return vm
}

上面的代码中,如果 vm._events 对象中不存在该事件的回调函数,就会初始化一个空数组来存储回调函数。如果该事件名称匹配了 hookRE 正则表达式,就会将 _hasHookEvent 标记为 true,这样可以在组件更新时快速判断是否需要调用生命周期钩子函数。

事件机制的运用

事件机制在 Vue.js 2.0 中广泛应用于组件间的通信和状态管理。以下是一些事件机制的运用场景:

父子组件间的通信

父组件可以在模板中使用 v-on 指令监听子组件触发的事件,如:


子组件在触发事件时,可以调用 $emit 方法并传递事件名称及数据:

this.$emit('custom-event', data)

非父子组件间的通信

对于非父子组件间的通信,可以使用一个名为 EventBus 的事件总线实现。EventBus 可以是一个简单的 Vue 实例,用来在组件之间进行事件传递。

首先,创建一个 EventBus 实例并导出:

import Vue from 'vue'
export const EventBus = new Vue()

然后,在需要传递事件的组件中引入 EventBus 实例,并使用 $emit 方法触发事件:

import { EventBus } from '@/event-bus.js'// 触发事件
EventBus.$emit('custom-event', data)

在需要监听事件的组件中也需要引入 EventBus 实例,并使用 $on 方法监听事件:

import { EventBus } from '@/event-bus.js'// 监听事件
EventBus.$on('custom-event', data => {// 处理事件
})

Vuex 状态管理

Vue.js 2.0 提供了一个名为 Vuex 的状态管理库,它可以帮助我们更好地管理组件状态,并且能够实现跨组件的状态共享。

Vuex 中的状态存储在一个中央的 store 中,可以通过 this.$store 在组件中访问。当组件需要修改状态时,可以通过提交一个 mutation 来改变状态,或者通过分发一个 action 来触发一系列的状态变更操作。

当状态发生变化时,所有使用该状态的组件都会得到通知,并进行相应的更新。

// 定义 store
import Vue from 'vue'
import Vuex from 'vuex'Vue.use(Vuex)const store = new Vuex.Store({state: {count: 0},mutations: {increment (state) {state.count++}}
})export default store
// 在组件中使用 state 和 mutation

以上就是 Vue.js 2.0 中事件机制的实现和运用,它们在实现组件间通信和状态管理方面提供了很大的便利。

总结

在 Vue.js 2.0 中,事件机制被广泛运用于实现组件之间的通信和状态管理。对于父子组件之间的通信,可以使用 props$emit 方法;对于非父子组件之间的通信,可以使用一个名为 EventBus 的事件总线实现;对于状态管理,可以使用 Vuex 库来实现状态存储和变更操作。这些机制的运用使得 Vue.js 的组件化开发更加方便和灵活。

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...