vue.js 源代码学习笔记 ----- instance event
/* @flow */ import { updateListeners } from '../vdom/helpers/index'
import { toArray, tip, hyphenate, formatComponentName } from '../util/index' export function initEvents (vm: Component) {
vm._events = Object.create(null)
vm._hasHookEvent = false
// init parent attached events 把父级的监听加载到vm中
const listeners = vm.$options._parentListeners
if (listeners) {
updateComponentListeners(vm, listeners)
}
} let target: Component
//绑定事件
function add (event, fn, once) {
if (once) {
target.$once(event, fn)
} else {
target.$on(event, fn)
}
} function remove (event, fn) {
target.$off(event, fn)
} export function updateComponentListeners (
vm: Component,
listeners: Object,
oldListeners: ?Object
) {
target = vm
updateListeners(listeners, oldListeners || {}, add, remove, vm)
} export function eventsMixin (Vue: Class<Component>) {
const hookRE = /^hook:/
Vue.prototype.$on = function (event: string | Array<string>, fn: Function): Component {
const vm: Component = this
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
if (hookRE.test(event)) {
vm._hasHookEvent = true
}
}
return vm
} 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
} 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
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]
if (!cbs) {
return vm
}
if (arguments.length === 1) {
vm._events[event] = null
return vm
}
// specific handler 在 vm._events 中移除事件
let cb
let i = cbs.length
while (i--) {
cb = cbs[i]
if (cb === fn || cb.fn === fn) {
cbs.splice(i, 1)
break
}
}
return vm
} 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}". ` +
//注意 html属性 是大小写铭感的, 你不能利用 v-on 来监听驼峰写法的事件, 在模板中
`Note that HTML attributes are case-insensitive and you cannot use ` +
`v-on to listen to camelCase events when using in-DOM templates. ` +
//你应该使用 show-one 来替代 showOne
`You should probably use "${hyphenate(event)}" instead of "${event}".`
)
}
}
let cbs = vm._events[event]
//执行events
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 源代码学习笔记 ----- instance event的更多相关文章
- vue.js 源代码学习笔记 ----- instance render
/* @flow */ import { warn, nextTick, toNumber, _toString, looseEqual, emptyObject, handleError, loos ...
- vue.js 源代码学习笔记 ----- instance state
/* @flow */ import Dep from '../observer/dep' import Watcher from '../observer/watcher' import { set ...
- vue.js 源代码学习笔记 ----- instance proxy
/* not type checking this file because flow doesn't play well with Proxy */ import config from 'core ...
- vue.js 源代码学习笔记 ----- instance init
/* @flow */ import config from '../config' import { initProxy } from './proxy' import { initState } ...
- vue.js 源代码学习笔记 ----- instance index
import { initMixin } from './init' import { stateMixin } from './state' import { renderMixin } from ...
- vue.js 源代码学习笔记 ----- instance inject
/* @flow */ import { hasSymbol } from 'core/util/env' import { warn } from '../util/index' import { ...
- vue.js 源代码学习笔记 ----- 工具方法 env
/* @flow */ /* globals MutationObserver */ import { noop } from 'shared/util' // can we use __proto_ ...
- vue.js 源代码学习笔记 ----- helpers.js
/* @flow */ import { parseFilters } from './parser/filter-parser' export function baseWarn (msg: str ...
- vue.js 源代码学习笔记 ----- html-parse.js
/** * Not type-checking this file because it's mostly vendor code. */ /*! * HTML Parser By John Resi ...
随机推荐
- wamp5.5.12安装re dis扩展
转载地址:http://hanqunfeng.iteye.com/blog/1984387 phpredis是个人觉得最好的一个php-redis客户端,因为其提供的function与redis的命令 ...
- kali 安装virtualbox
安装virualbox 的三大步: 1.添加源: Add the following line to your /etc/apt/sources.list: deb http://download.v ...
- 在Linux终端管理文件你要知道的11个命令
LS - 列表文件 ls命令列出目录中的文件. 默认情况下,使用ls列出当前目录下的文件. 2 你也可以列出文件递归-也就是说,列出所有文件在当前目录中的目录-使用ls -R.LS还可以列出在其他目录 ...
- nxp的layerscape系列芯片中的rcw指定了一些什么信息
答:指定了一些可以配置的硬件信息(如可以配置uart相关的引脚功能).引导镜像(uboot)的读取地址以及从何种介质(flash,sd)启动系统的信息
- Vuex访问状态对象的方法
除了<Vuex最基本样例>中的方法外,还有两种方法访问状态对象state: 只需要改app.vue文件 方法一:引入computed <template> <div id ...
- imagemagick在windows下安装(转,有改动)
原文地址:http://blog.csdn.net/royal_coffee/article/details/1602933 注意:本補述僅提供 Windows 下安裝建議. 1. 到 http:// ...
- Matlab 日期频次统计
一.孕妇建档月份频次统计 源数据样本,为某医院一段时间内的孕妇建档时间 2015-04-22 10:12:522014-11-21 17:16:472013-12-16 17:35:442013-12 ...
- htop 比top更好用的top
安装 sudo apt-get install htop 使用 htop
- awardRotate.js
(function($) { var supportedCSS,styles=document.getElementsByTagName("head")[0].style,toCh ...
- linux基础之Vim