/* @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的更多相关文章

  1. vue.js 源代码学习笔记 ----- instance render

    /* @flow */ import { warn, nextTick, toNumber, _toString, looseEqual, emptyObject, handleError, loos ...

  2. vue.js 源代码学习笔记 ----- instance state

    /* @flow */ import Dep from '../observer/dep' import Watcher from '../observer/watcher' import { set ...

  3. vue.js 源代码学习笔记 ----- instance proxy

    /* not type checking this file because flow doesn't play well with Proxy */ import config from 'core ...

  4. vue.js 源代码学习笔记 ----- instance init

    /* @flow */ import config from '../config' import { initProxy } from './proxy' import { initState } ...

  5. vue.js 源代码学习笔记 ----- instance index

    import { initMixin } from './init' import { stateMixin } from './state' import { renderMixin } from ...

  6. vue.js 源代码学习笔记 ----- instance inject

    /* @flow */ import { hasSymbol } from 'core/util/env' import { warn } from '../util/index' import { ...

  7. vue.js 源代码学习笔记 ----- 工具方法 env

    /* @flow */ /* globals MutationObserver */ import { noop } from 'shared/util' // can we use __proto_ ...

  8. vue.js 源代码学习笔记 ----- helpers.js

    /* @flow */ import { parseFilters } from './parser/filter-parser' export function baseWarn (msg: str ...

  9. vue.js 源代码学习笔记 ----- html-parse.js

    /** * Not type-checking this file because it's mostly vendor code. */ /*! * HTML Parser By John Resi ...

随机推荐

  1. wamp5.5.12安装re dis扩展

    转载地址:http://hanqunfeng.iteye.com/blog/1984387 phpredis是个人觉得最好的一个php-redis客户端,因为其提供的function与redis的命令 ...

  2. kali 安装virtualbox

    安装virualbox 的三大步: 1.添加源: Add the following line to your /etc/apt/sources.list: deb http://download.v ...

  3. 在Linux终端管理文件你要知道的11个命令

    LS - 列表文件 ls命令列出目录中的文件. 默认情况下,使用ls列出当前目录下的文件. 2 你也可以列出文件递归-也就是说,列出所有文件在当前目录中的目录-使用ls -R.LS还可以列出在其他目录 ...

  4. nxp的layerscape系列芯片中的rcw指定了一些什么信息

    答:指定了一些可以配置的硬件信息(如可以配置uart相关的引脚功能).引导镜像(uboot)的读取地址以及从何种介质(flash,sd)启动系统的信息

  5. Vuex访问状态对象的方法

    除了<Vuex最基本样例>中的方法外,还有两种方法访问状态对象state: 只需要改app.vue文件 方法一:引入computed <template> <div id ...

  6. imagemagick在windows下安装(转,有改动)

    原文地址:http://blog.csdn.net/royal_coffee/article/details/1602933 注意:本補述僅提供 Windows 下安裝建議. 1. 到 http:// ...

  7. Matlab 日期频次统计

    一.孕妇建档月份频次统计 源数据样本,为某医院一段时间内的孕妇建档时间 2015-04-22 10:12:522014-11-21 17:16:472013-12-16 17:35:442013-12 ...

  8. htop 比top更好用的top

    安装 sudo apt-get install htop 使用 htop

  9. awardRotate.js

    (function($) { var supportedCSS,styles=document.getElementsByTagName("head")[0].style,toCh ...

  10. linux基础之Vim