|
1 |
| -import { getCurrentInstance } from 'vue' |
| 1 | +import { setDevtoolsHook, ComponentPublicInstance } from 'vue' |
2 | 2 |
|
3 |
| -export const attachEmitListener = () => { |
4 |
| - return { |
5 |
| - beforeCreate() { |
6 |
| - let events: Record<string, unknown[]> = {} |
7 |
| - ;(this as any).__emitted = events |
8 |
| - const originalEmit = getCurrentInstance()!.emit |
9 |
| - getCurrentInstance()!.emit = (event: string, ...args: unknown[]) => { |
10 |
| - events[event] |
11 |
| - ? (events[event] = [...events[event], [...args]]) |
12 |
| - : (events[event] = [[...args]]) |
| 3 | +const enum DevtoolsHooks { |
| 4 | + COMPONENT_EMIT = 'component:emit' |
| 5 | +} |
| 6 | + |
| 7 | +export const attachEmitListener = (vm: ComponentPublicInstance) => { |
| 8 | + let events: Record<string, unknown[]> = {} |
| 9 | + ;(vm as any).__emitted = events |
| 10 | + // use devtools capture this "emit" |
| 11 | + setDevtoolsHook(createDevTools(events)) |
| 12 | +} |
| 13 | + |
| 14 | +function createDevTools(events) { |
| 15 | + const devTools: any = { |
| 16 | + emit(type, ...payload) { |
| 17 | + if (type !== DevtoolsHooks.COMPONENT_EMIT) return |
| 18 | + |
| 19 | + // The first argument is root component |
| 20 | + // The second argument is vm |
| 21 | + // The third argument is event |
| 22 | + // The fourth argument is args of event |
| 23 | + recordEvent(events, payload[2], payload[3]) |
| 24 | + wrapperWarn() |
| 25 | + } |
| 26 | + } |
| 27 | + |
| 28 | + return devTools |
| 29 | +} |
| 30 | + |
| 31 | +function recordEvent(events, event, args) { |
| 32 | + events[event] |
| 33 | + ? (events[event] = [...events[event], [...args]]) |
| 34 | + : (events[event] = [[...args]]) |
| 35 | +} |
13 | 36 |
|
14 |
| - // Vue will warn you if you emit an event that is not declared in `emits` and |
15 |
| - // if the parent is not listening for that event. |
16 |
| - // since we intercept the event, we are never listening for it explicitly on the |
17 |
| - // Parent component. Swallow those events then restore the console.warn. |
18 |
| - // TODO: find out if this is doable using `app.config.warnHandler` (does not appear |
19 |
| - // work right now). https://github.com/vuejs/vue-test-utils-next/issues/197 |
20 |
| - const consoleWarnSave = console.warn |
21 |
| - console.warn = (msg: string, ...rest: unknown[]) => { |
22 |
| - if (msg.includes('[Vue warn]: Component emitted event')) { |
23 |
| - return |
24 |
| - } else { |
25 |
| - consoleWarnSave(msg, ...rest) |
26 |
| - } |
27 |
| - } |
28 |
| - originalEmit(event, ...args) |
29 |
| - console.warn = consoleWarnSave |
30 |
| - return [event, ...args] |
31 |
| - } |
| 37 | +// Vue will warn you if you emit an event that is not declared in `emits` and |
| 38 | +// if the parent is not listening for that event. |
| 39 | +// since we intercept the event, we are never listening for it explicitly on the |
| 40 | +// Parent component. Swallow those events then restore the console.warn. |
| 41 | +// TODO: find out if this is doable using `app.config.warnHandler` (does not appear |
| 42 | +// work right now). https://github.com/vuejs/vue-test-utils-next/issues/197 |
| 43 | +function wrapperWarn() { |
| 44 | + const consoleWarnSave = console.warn |
| 45 | + console.warn = (msg: string, ...rest: unknown[]) => { |
| 46 | + if (msg.includes('[Vue warn]: Component emitted event')) { |
| 47 | + return |
| 48 | + } else { |
| 49 | + consoleWarnSave(msg, ...rest) |
32 | 50 | }
|
33 | 51 | }
|
| 52 | + console.warn = consoleWarnSave |
34 | 53 | }
|
0 commit comments