support $on multi event (#4860)

This commit is contained in:
kingwl 2017-02-15 17:39:53 -06:00 committed by Evan You
parent 0598ab0c64
commit 8bb6c2bdaa
4 changed files with 27 additions and 8 deletions

View File

@ -41,7 +41,7 @@ declare interface Component {
$set: (obj: Array<mixed> | Object, key: mixed, val: mixed) => void;
$delete: (obj: Object, key: string) => void;
$watch: (expOrFn: string | Function, cb: Function, options?: Object) => Function;
$on: (event: string, fn: Function) => Component;
$on: (event: string | Array<string>, fn: Function) => Component;
$once: (event: string, fn: Function) => Component;
$off: (event?: string, fn?: Function) => Component;
$emit: (event: string, ...args: Array<mixed>) => Component;

View File

@ -38,13 +38,19 @@ export function updateComponentListeners (
export function eventsMixin (Vue: Class<Component>) {
const hookRE = /^hook:/
Vue.prototype.$on = function (event: string, fn: Function): Component {
Vue.prototype.$on = function (event: string | Array<string>, fn: Function): Component {
const vm: Component = this
;(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
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
}

View File

@ -18,6 +18,19 @@ describe('Instance methods events', () => {
expect(spy).toHaveBeenCalledWith(1, 2, 3, 4)
})
it('$on multi event', () => {
vm.$on(['test1', 'test2'], function () {
expect(this).toBe(vm)
spy.apply(this, arguments)
})
vm.$emit('test1', 1, 2, 3, 4)
expect(spy.calls.count()).toBe(1)
expect(spy).toHaveBeenCalledWith(1, 2, 3, 4)
vm.$emit('test2', 5, 6, 7, 8)
expect(spy.calls.count()).toBe(2)
expect(spy).toHaveBeenCalledWith(5, 6, 7, 8)
})
it('$once', () => {
vm.$once('test', spy)
vm.$emit('test', 1, 2, 3)

2
types/vue.d.ts vendored
View File

@ -59,7 +59,7 @@ export declare class Vue {
callback: WatchHandler<this, T>,
options?: WatchOptions
): (() => void);
$on(event: string, callback: Function): this;
$on(event: string | string[], callback: Function): this;
$once(event: string, callback: Function): this;
$off(event?: string, callback?: Function): this;
$emit(event: string, ...args: any[]): this;