Skip to content

Commit f45e0e0

Browse files
committed
feat: add createApp
1 parent 3346d10 commit f45e0e0

File tree

3 files changed

+63
-23
lines changed

3 files changed

+63
-23
lines changed

README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,27 @@ watch(() => {
369369

370370
</details>
371371

372+
### createApp
373+
374+
<details>
375+
<summary>
376+
⚠️ <code>createApp()</code> is global
377+
</summary>
378+
379+
In Vue 3, `createApp()` is introduced to provide context(plugin, components, etc.) isolation between app instances. Due the the design of Vue 2, in this plugin, we provide `createApp()` as a forward compatible API which is just an alias of the global.
380+
381+
```ts
382+
const app1 = createApp(RootComponent1)
383+
app1.component('Foo', Foo) // equivlate as Vue.component('Foo', Foo)
384+
app1.use(VueRouter) // equivlate as Vue.use(VueRouter)
385+
386+
const app2 = createApp(RootComponent2)
387+
app2.component('Bar', Bar) // equivlate as Vue.use('Bar', Bar)
388+
```
389+
390+
</details>
391+
392+
372393
### Missing APIs
373394

374395
The following APIs introduced in Vue 3 are not available in this plugin.

src/createApp.ts

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import Vue from 'vue'
1+
import type Vue from 'vue'
22
import { VueConstructor } from 'vue/types/umd'
3-
import { currentVue } from './runtimeContext'
3+
import { getCurrentVue } from './runtimeContext'
44
import { warn } from './utils'
55

66
export interface App {
@@ -14,9 +14,9 @@ export interface App {
1414
}
1515

1616
export function createApp(rootComponent: any, rootProps: any = undefined): App {
17-
const V = currentVue!
17+
const V = getCurrentVue()!
1818

19-
let mountedVM: Vue | undefined
19+
let mountedVM: Vue | undefined = undefined
2020

2121
return {
2222
config: V.config,
@@ -26,10 +26,7 @@ export function createApp(rootComponent: any, rootProps: any = undefined): App {
2626
directive: V.directive.bind(V),
2727
mount: (el, hydrating) => {
2828
if (!mountedVM) {
29-
mountedVM = new V({
30-
propsData: rootProps,
31-
render: (h) => h(rootComponent),
32-
})
29+
mountedVM = new V({ propsData: rootProps, ...rootComponent })
3330
mountedVM.$mount(el, hydrating)
3431
return mountedVM
3532
} else {

test/createApp.spec.js

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,19 @@
1-
const { createApp, defineComponent } = require('../src')
2-
const { nextTick } = require('process')
3-
4-
describe('setup', () => {
5-
beforeEach(() => {
6-
warn = jest.spyOn(global.console, 'error').mockImplementation(() => null)
7-
})
8-
afterEach(() => {
9-
warn.mockRestore()
10-
})
1+
const Vue = require('vue/dist/vue.common.js')
2+
const { createApp, defineComponent, ref, h } = require('../src')
113

4+
describe('createApp', () => {
125
it('should work', async () => {
13-
const app = createApp({
6+
const vm = new Vue({
147
setup() {
158
return {
169
a: ref(1),
1710
}
1811
},
1912
template: '<p>{{a}}</p>',
20-
})
21-
const vm = app.mount()
13+
}).$mount()
2214

23-
await nextTick()
15+
await Vue.nextTick()
16+
expect(vm.a).toBe(1)
2417
expect(vm.$el.textContent).toBe('1')
2518
})
2619

@@ -38,7 +31,36 @@ describe('setup', () => {
3831
)
3932
const vm = app.mount()
4033

41-
await nextTick()
34+
await Vue.nextTick()
35+
expect(vm.$el.textContent).toBe('foobar')
36+
})
37+
38+
it('should work with components', async () => {
39+
const Foo = defineComponent({
40+
props: {
41+
msg: {
42+
type: String,
43+
required: true,
44+
},
45+
},
46+
template: '<p>{{msg}}</p>',
47+
})
48+
49+
const app = createApp(
50+
defineComponent({
51+
props: {
52+
msg: String,
53+
},
54+
template: '<Foo :msg="msg"/>',
55+
}),
56+
{
57+
msg: 'foobar',
58+
}
59+
)
60+
app.component('Foo', Foo)
61+
const vm = app.mount()
62+
63+
await Vue.nextTick()
4264
expect(vm.$el.textContent).toBe('foobar')
4365
})
4466
})

0 commit comments

Comments
 (0)