/
helper.ts
117 lines (103 loc) · 2.64 KB
/
helper.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import Vue, { VNode, ComponentOptions, VueConstructor } from 'vue'
import { ComponentInstance } from '../component'
import {
ComponentInternalInstance,
getCurrentInstance,
getVueConstructor,
Slot,
} from '../runtimeContext'
import { warn } from './utils'
export function getCurrentInstanceForFn(
hook: string,
target?: ComponentInternalInstance | null
): ComponentInternalInstance | null {
target = target || getCurrentInstance()
if (__DEV__ && !target) {
warn(
`${hook} is called when there is no active component instance to be ` +
`associated with. ` +
`Lifecycle injection APIs can only be used during execution of setup().`
)
}
return target
}
export function defineComponentInstance<V extends Vue = Vue>(
Ctor: VueConstructor<V>,
options: ComponentOptions<V> = {}
) {
const silent = Ctor.config.silent
Ctor.config.silent = true
const vm = new Ctor(options)
Ctor.config.silent = silent
return vm
}
export function isComponentInstance(obj: any) {
const Vue = getVueConstructor()
return Vue && obj instanceof Vue
}
export function createSlotProxy(vm: ComponentInstance, slotName: string): Slot {
return ((...args: any) => {
if (!vm.$scopedSlots[slotName]) {
if (__DEV__)
return warn(
`slots.${slotName}() got called outside of the "render()" scope`,
vm
)
return
}
return vm.$scopedSlots[slotName]!.apply(vm, args)
}) as Slot
}
export function resolveSlots(
slots: { [key: string]: Function } | void,
normalSlots: { [key: string]: VNode[] | undefined }
): { [key: string]: true } {
let res: { [key: string]: true }
if (!slots) {
res = {}
} else if (slots._normalized) {
// fast path 1: child component re-render only, parent did not change
return slots._normalized as any
} else {
res = {}
for (const key in slots) {
if (slots[key] && key[0] !== '$') {
res[key] = true
}
}
}
// expose normal slots on scopedSlots
for (const key in normalSlots) {
if (!(key in res)) {
res[key] = true
}
}
return res
}
let vueInternalClasses:
| {
Watcher: any
Dep: any
}
| undefined
export const getVueInternalClasses = () => {
if (!vueInternalClasses) {
const vm: any = defineComponentInstance(getVueConstructor(), {
computed: {
value() {
return 0
},
},
})
// to get Watcher class
const Watcher = vm._computedWatchers.value.constructor
// to get Dep class
const Dep = vm._data.__ob__.dep.constructor
vueInternalClasses = {
Watcher,
Dep,
}
vm.$destroy()
}
return vueInternalClasses
}