/
install.ts
69 lines (62 loc) · 1.65 KB
/
install.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
import { AnyObject } from './types/basic'
import { hasSymbol, hasOwn, isPlainObject, assert } from './utils'
import { isRef } from './reactivity'
import { setCurrentVue, currentVue } from './runtimeContext'
import { VueConstructor } from 'vue'
/**
* Helper that recursively merges two data objects together.
*/
function mergeData(from: AnyObject, to: AnyObject): Object {
if (!from) return to
if (!to) return from
let key: any
let toVal: any
let fromVal: any
const keys = hasSymbol ? Reflect.ownKeys(from) : Object.keys(from)
for (let i = 0; i < keys.length; i++) {
key = keys[i]
// in case the object is already observed...
if (key === '__ob__') continue
toVal = to[key]
fromVal = from[key]
if (!hasOwn(to, key)) {
to[key] = fromVal
} else if (
toVal !== fromVal &&
isPlainObject(toVal) &&
!isRef(toVal) &&
isPlainObject(fromVal) &&
!isRef(fromVal)
) {
mergeData(fromVal, toVal)
}
}
return to
}
export function install(
Vue: VueConstructor,
_install: (Vue: VueConstructor) => void
) {
if (currentVue && currentVue === Vue) {
if (__DEV__) {
assert(
false,
'already installed. Vue.use(plugin) should be called only once'
)
}
return
}
Vue.config.optionMergeStrategies.setup = function (
parent: Function,
child: Function
) {
return function mergedSetupFn(props: any, context: any) {
return mergeData(
typeof parent === 'function' ? parent(props, context) || {} : undefined,
typeof child === 'function' ? child(props, context) || {} : undefined
)
}
}
setCurrentVue(Vue)
_install(Vue)
}