Vue3.x createApp
Alphawq Vue3
# createApp
# 使用
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
1
2
3
4
2
3
4
# 定义
let renderer
function ensureRenderer() {
return renderer || (renderer = createRenderer(rendererOptions))
}
const createApp = (...args) => {
const app = ensureRenderer().createApp(...args)
// ...
const { mount } = app
// mount 方法被重写了
app.mount = (containerOrSelector) => {
// ...
}
return app
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# createRenderer
function createRenderer(options) {
return baseCreateRenderer(options)
}
function baseCreateRenderer(options, createHydrationFns) {
// ...
const render = (vnode, container, isSVG) => {
// vnode 不存在
if (vnode == null) {
if (container._vnode) {
unmount(container._vnode, null, null, true)
}
} else {
patch(container._vnode || null, vnode, container, null, null, null, isSVG)
}
flushPostFlushCbs()
container._vnode = vnode
}
return {
render,
hydrate,
createApp: createAppAPI(render, hydrate),
}
}
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
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
# createAppAPI
let uid = 0
function createAppContext() {
return {
app: null,
config: {
isNativeTag: NO,
performance: false,
globalProperties: {},
optionMergeStrategies: {},
errorHandler: undefined,
warnHandler: undefined,
compilerOptions: {},
},
mixins: [],
components: {},
directives: {},
provides: Object.create(null),
optionsCache: new WeakMap(),
propsCache: new WeakMap(),
emitsCache: new WeakMap(),
}
}
function createAppAPI(render, hydrate) {
return function createApp(rootComponent, rootProps = null) {
if (rootProps != null && !isObject(rootProps)) {
warn$1(`root props passed to app.mount() must be an object.`)
rootProps = null
}
const context = createAppContext()
const installedPlugins = new Set()
let isMounted = false
const app = (context.app = {
_uid: uid++,
_component: rootComponent,
_props: rootProps,
_container: null,
_context: context,
_instance: null,
version,
get config() {
return context.config
},
set config(v) {
// ...
},
use(plugin, ...options) {
// ...
return app
},
mixin(mixin) {
// ...
return app
},
component(name, component) {
// ...
return app
},
directive(name, directive) {
// ...
return app
},
mount(rootContainer, isHydrate, isSVG) {
// ...
},
unmount() {
// ...
},
provide(key, value) {
// ...
return app
},
})
return app
}
}
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
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
可以看到 Vue3 采用了一种无 new 构造的方式创造了一个 app 应用实例。这也使得在 vue2 中使用 vue.prototype.xxx
来定义所有组件实例都能访问的方法和属性的方式在 vue3 中将不再支持,
- vue2
import axios from 'axios'
Vue.prototype.$axios = axios
1
2
3
2
3
- vue3
import axios from 'axios'
const app = createApp({})
app.config.globalProperties.$axios = axios
// 在组件中可以通过this访问
this.$axios(/*...*/)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
并且像之前在 Vue 构造器上定义的许多静态方法,现在也都变成了通过 app 实例来调用
app.use()
app.component()
app.mixin()
app.directive()
app.mixin()
1
2
3
4
5
2
3
4
5