写在前面

因为对Vue.js很感兴趣,而且平时工作的技术栈也是Vue.js,这几个月花了些时间研究学习了一下Vue.js源码,并做了总结与输出。
文章的原地址:https://github.com/answershuto/learnVue。
在学习过程中,为Vue加上了中文的注释https://github.com/answershuto/learnVue/tree/master/vue-src,希望可以对其他想学习Vue源码的小伙伴有所帮助。
可能会有理解存在偏差的地方,欢迎提issue指出,共同学习,共同进步。
Vue事件API
众所周知,Vue.js为我们提供了四个事件API,分别是$on](https://cn.vuejs.org/v2/api/#vm-on-event-callback),[$once,$off](https://cn.vuejs.org/v2/api/#vm-off-event-callback),[$emit。
初始化事件
初始化事件在vm上创建一个_events对象,用来存放事件。_events的内容如下:
{
eventName: [func1, func2, func3]
}
存放事件名以及对应执行方法。
/*初始化事件*/
export function initEvents (vm: Component) {
/*在vm上创建一个_events对象,用来存放事件。*/
vm._events = Object.create(null)
/*这个bool标志位来表明是否存在钩子,而不需要通过哈希表的方法来查找是否有钩子,这样做可以减少不必要的开销,优化性能。*/
vm._hasHookEvent = false
// init parent attached events
/*初始化父组件attach的事件*/
const listeners = vm.$options._parentListeners
if (listeners) {
updateComponentListeners(vm, listeners)
}
}
$on
$on方法用来在vm实例上监听一个自定义事件,该事件可用$emit触发。
Vue.prototype.$on = function (event: string | Array<string>, fn: Function): Component {
const vm: Component = this
/*如果是数组的时候,则递归$on,为每一个成员都绑定上方法*/
if (Array.isArray(event)) {
for (let i = 0, l = event.length; i < l; i++) {
this.$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 lookup
/*这里在注册事件的时候标记bool值也就是个标志位来表明存在钩子,而不需要通过哈希表的方法来查找是否有钩子,这样做可以减少不必要的开销,优化性能。*/
if (hookRE.test(event)) {
vm._hasHookEvent = true
}
}
return vm
}
$once
$once监听一个只能触发一次的事件,在触发以后会自动移除该事件。
Vue.prototype.$once = function (event: string, fn: Function): Component {
const vm: Component = this
function on () {
/*在第一次执行的时候将该事件销毁*/
vm.$off(event, on)
/*执行注册的方法*/
fn.apply(vm, arguments)
}
on.fn = fn
vm.$on(event, on)
return vm
}
$off
$off用来移除自定义事件
Vue.prototype.$off = function (event?: string | Array<string>, fn?: Function): Component {
const vm: Component = this
// all
/*如果不传参数则注销所有事件*/
if (!arguments.length) {
vm._events = Object.create(null)
return vm
}
// array of events
/*如果event是数组则递归注销事件*/
if (Array.isArray(event)) {
for (let i = 0, l = event.length; i < l; i++) {
this.$off(event[i], fn)
}
return vm
}
// specific event
const cbs = vm._events[event]
/*Github:https://github.com/answershuto*/
/*本身不存在该事件则直接返回*/
if (!cbs) {
return vm
}
/*如果只传了event参数则注销该event方法下的所有方法*/
if (arguments.length === 1) {
vm._events[event] = null
return vm
}
// specific handler
/*遍历寻找对应方法并删除*/
let cb
let i = cbs.length
while (i--) {
cb = cbs[i]
if (cb === fn || cb.fn === fn) {
cbs.splice(i, 1)
break
}
}
return vm
}
$emit
$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]) {
tip(
`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) : cbs
const args = toArray(arguments, 1)
/*遍历执行*/
for (let i = 0, l = cbs.length; i < l; i++) {
cbs[i].apply(vm, args)
}
}
return vm
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# Vue.js
# 事件机制
# 浅谈Vue2.0父子组件间事件派发机制
# 一篇文章带你了解vue.js的事件循环机制
# vue @click与@click.native
# 及vue事件机制的使用分析
# 递归
# 自定义
# 遍历
# 而不
# 这样做
# 方法来
# 创建一个
# 移除
# 可以减少
# 是个
# 会有
# 也就
# 上了
# 感兴趣
# 对其
# 不存在
# 花了
# 他想
# 这几个
# 转换成
相关文章:
Android自定义控件实现温度旋转按钮效果
北京网站制作公司哪家好一点,北京租房网站有哪些?
,购物网站怎么盈利呢?
已有域名和空间,如何快速搭建网站?
常州企业网站制作公司,全国继续教育网怎么登录?
专业网站制作服务公司,有哪些网站可以免费发布招聘信息?
,怎么用自己头像做动态表情包?
北京专业网站制作设计师招聘,北京白云观官方网站?
早安海报制作网站推荐大全,企业早安海报怎么每天更换?
如何设置并定期更换建站之星安全管理员密码?
智能起名网站制作软件有哪些,制作logo的软件?
洛阳网站制作公司有哪些,洛阳的招聘网站都有哪些?
C++如何使用std::optional?(处理可选值)
制作无缝贴图网站有哪些,3dmax无缝贴图怎么调?
建站之星如何取消后台验证码生成?
相亲简历制作网站推荐大全,新相亲大会主持人小萍萍资料?
香港服务器选型指南:免备案配置与高效建站方案解析
在线教育网站制作平台,山西立德教育官网?
台州网站建设制作公司,浙江手机无犯罪记录证明怎么开?
成都网站制作价格表,现在成都广电的单独网络宽带有多少的,资费是什么情况呢?
网站制作知乎推荐,想做自己的网站用什么工具比较好?
郑州企业网站制作公司,郑州招聘网站有哪些?
建站之星会员如何解锁更多建站功能?
图册素材网站设计制作软件,图册的导出方式有几种?
如何在IIS中配置站点IP、端口及主机头?
如何在香港服务器上快速搭建免备案网站?
大连网站设计制作招聘信息,大连投诉网站有哪些?
C++中的Pimpl idiom是什么,有什么好处?(隐藏实现)
详解一款开源免费的.NET文档操作组件DocX(.NET组件介绍之一)
三星网站视频制作教程下载,三星w23网页如何全屏?
如何在Ubuntu系统下快速搭建WordPress个人网站?
如何通过VPS建站实现广告与增值服务盈利?
如何快速登录WAP自助建站平台?
宝塔新建站点为何无法访问?如何排查?
制作ppt免费网站有哪些,有哪些比较好的ppt模板下载网站?
企业网站制作费用多少,企业网站空间一般需要多大,费用是多少?
小捣蛋自助建站系统:数据分析与安全设置双核驱动网站优化
如何规划企业建站流程的关键步骤?
制作网站的软件下载免费,今日头条开宝箱老是需要下载怎么回事?
无锡营销型网站制作公司,无锡网选车牌流程?
建站之星×万网:智能建站系统+自助建站平台一键生成
如何彻底删除建站之星生成的Banner?
制作网站哪家好,cc、.co、.cm哪个域名更适合做网站?
建站主机是什么?如何选择适合的建站主机?
如何通过网站建站时间优化SEO与用户体验?
如何快速搭建二级域名独立网站?
如何在阿里云香港服务器快速搭建网站?
网站视频怎么制作,哪个网站可以免费收看好莱坞经典大片?
在线制作视频网站免费,都有哪些好的动漫网站?
关于BootStrap modal 在IOS9中不能弹出的解决方法(IOS 9 bootstrap modal ios 9 noticework)
*请认真填写需求信息,我们会在24小时内与您取得联系。