diff --git a/flow/component.js b/flow/component.js index f4a614dd9de..fa7c99b8df6 100644 --- a/flow/component.js +++ b/flow/component.js @@ -36,7 +36,7 @@ declare interface Component { $set: (obj: Array | 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, fn: Function) => Component; $once: (event: string, fn: Function) => Component; $off: (event?: string, fn?: Function) => Component; $emit: (event: string, ...args: Array) => Component; diff --git a/src/core/instance/events.js b/src/core/instance/events.js index fa7f5f4fcee..af3fe01a381 100644 --- a/src/core/instance/events.js +++ b/src/core/instance/events.js @@ -38,13 +38,19 @@ export function updateComponentListeners ( export function eventsMixin (Vue: Class) { const hookRE = /^hook:/ - Vue.prototype.$on = function (event: string, fn: Function): Component { + Vue.prototype.$on = function (event: string | Array, 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 } diff --git a/test/unit/features/instance/methods-events.spec.js b/test/unit/features/instance/methods-events.spec.js index 270e187814f..a71022a6edb 100644 --- a/test/unit/features/instance/methods-events.spec.js +++ b/test/unit/features/instance/methods-events.spec.js @@ -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) diff --git a/types/vue.d.ts b/types/vue.d.ts index 823828a6d5d..771d9e41d26 100644 --- a/types/vue.d.ts +++ b/types/vue.d.ts @@ -53,7 +53,7 @@ export declare class Vue { callback: WatchHandler, 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;