refactor: adjust createApp
related API signatures
BREAKING CHANGE: `createApp` API has been adjusted. - `createApp()` now accepts the root component, and optionally a props object to pass to the root component. - `app.mount()` now accepts a single argument (the root container) - `app.unmount()` no longer requires arguments. New behavior looks like the following: ``` js const app = createApp(RootComponent) app.mount('#app') app.unmount() ```
This commit is contained in:
parent
eacd390992
commit
c07751fd36
@ -30,18 +30,18 @@ describe('api: createApp', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const root1 = nodeOps.createElement('div')
|
const root1 = nodeOps.createElement('div')
|
||||||
createApp().mount(Comp, root1)
|
createApp(Comp).mount(root1)
|
||||||
expect(serializeInner(root1)).toBe(`0`)
|
expect(serializeInner(root1)).toBe(`0`)
|
||||||
|
|
||||||
// mount with props
|
// mount with props
|
||||||
const root2 = nodeOps.createElement('div')
|
const root2 = nodeOps.createElement('div')
|
||||||
const app2 = createApp()
|
const app2 = createApp(Comp, { count: 1 })
|
||||||
app2.mount(Comp, root2, { count: 1 })
|
app2.mount(root2)
|
||||||
expect(serializeInner(root2)).toBe(`1`)
|
expect(serializeInner(root2)).toBe(`1`)
|
||||||
|
|
||||||
// remount warning
|
// remount warning
|
||||||
const root3 = nodeOps.createElement('div')
|
const root3 = nodeOps.createElement('div')
|
||||||
app2.mount(Comp, root3)
|
app2.mount(root3)
|
||||||
expect(serializeInner(root3)).toBe(``)
|
expect(serializeInner(root3)).toBe(``)
|
||||||
expect(`already been mounted`).toHaveBeenWarned()
|
expect(`already been mounted`).toHaveBeenWarned()
|
||||||
})
|
})
|
||||||
@ -59,18 +59,14 @@ describe('api: createApp', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const root = nodeOps.createElement('div')
|
const root = nodeOps.createElement('div')
|
||||||
const app = createApp()
|
const app = createApp(Comp)
|
||||||
app.mount(Comp, root)
|
app.mount(root)
|
||||||
|
|
||||||
app.unmount(root)
|
app.unmount(root)
|
||||||
expect(serializeInner(root)).toBe(``)
|
expect(serializeInner(root)).toBe(``)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('provide', () => {
|
test('provide', () => {
|
||||||
const app = createApp()
|
|
||||||
app.provide('foo', 1)
|
|
||||||
app.provide('bar', 2)
|
|
||||||
|
|
||||||
const Root = {
|
const Root = {
|
||||||
setup() {
|
setup() {
|
||||||
// test override
|
// test override
|
||||||
@ -87,25 +83,16 @@ describe('api: createApp', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const app = createApp(Root)
|
||||||
|
app.provide('foo', 1)
|
||||||
|
app.provide('bar', 2)
|
||||||
|
|
||||||
const root = nodeOps.createElement('div')
|
const root = nodeOps.createElement('div')
|
||||||
app.mount(Root, root)
|
app.mount(root)
|
||||||
expect(serializeInner(root)).toBe(`3,2`)
|
expect(serializeInner(root)).toBe(`3,2`)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('component', () => {
|
test('component', () => {
|
||||||
const app = createApp()
|
|
||||||
|
|
||||||
const FooBar = () => 'foobar!'
|
|
||||||
app.component('FooBar', FooBar)
|
|
||||||
expect(app.component('FooBar')).toBe(FooBar)
|
|
||||||
|
|
||||||
app.component('BarBaz', () => 'barbaz!')
|
|
||||||
|
|
||||||
app.component('BarBaz', () => 'barbaz!')
|
|
||||||
expect(
|
|
||||||
'Component "BarBaz" has already been registered in target app.'
|
|
||||||
).toHaveBeenWarnedTimes(1)
|
|
||||||
|
|
||||||
const Root = {
|
const Root = {
|
||||||
// local override
|
// local override
|
||||||
components: {
|
components: {
|
||||||
@ -122,33 +109,29 @@ describe('api: createApp', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const app = createApp(Root)
|
||||||
|
|
||||||
|
const FooBar = () => 'foobar!'
|
||||||
|
app.component('FooBar', FooBar)
|
||||||
|
expect(app.component('FooBar')).toBe(FooBar)
|
||||||
|
|
||||||
|
app.component('BarBaz', () => 'barbaz!')
|
||||||
|
|
||||||
|
app.component('BarBaz', () => 'barbaz!')
|
||||||
|
expect(
|
||||||
|
'Component "BarBaz" has already been registered in target app.'
|
||||||
|
).toHaveBeenWarnedTimes(1)
|
||||||
|
|
||||||
const root = nodeOps.createElement('div')
|
const root = nodeOps.createElement('div')
|
||||||
app.mount(Root, root)
|
app.mount(root)
|
||||||
expect(serializeInner(root)).toBe(`<div>foobar!barbaz-local!</div>`)
|
expect(serializeInner(root)).toBe(`<div>foobar!barbaz-local!</div>`)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('directive', () => {
|
test('directive', () => {
|
||||||
const app = createApp()
|
|
||||||
|
|
||||||
const spy1 = jest.fn()
|
const spy1 = jest.fn()
|
||||||
const spy2 = jest.fn()
|
const spy2 = jest.fn()
|
||||||
const spy3 = jest.fn()
|
const spy3 = jest.fn()
|
||||||
|
|
||||||
const FooBar = { mounted: spy1 }
|
|
||||||
app.directive('FooBar', FooBar)
|
|
||||||
expect(app.directive('FooBar')).toBe(FooBar)
|
|
||||||
|
|
||||||
app.directive('BarBaz', {
|
|
||||||
mounted: spy2
|
|
||||||
})
|
|
||||||
|
|
||||||
app.directive('BarBaz', {
|
|
||||||
mounted: spy2
|
|
||||||
})
|
|
||||||
expect(
|
|
||||||
'Directive "BarBaz" has already been registered in target app.'
|
|
||||||
).toHaveBeenWarnedTimes(1)
|
|
||||||
|
|
||||||
const Root = {
|
const Root = {
|
||||||
// local override
|
// local override
|
||||||
directives: {
|
directives: {
|
||||||
@ -165,8 +148,25 @@ describe('api: createApp', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const app = createApp(Root)
|
||||||
|
|
||||||
|
const FooBar = { mounted: spy1 }
|
||||||
|
app.directive('FooBar', FooBar)
|
||||||
|
expect(app.directive('FooBar')).toBe(FooBar)
|
||||||
|
|
||||||
|
app.directive('BarBaz', {
|
||||||
|
mounted: spy2
|
||||||
|
})
|
||||||
|
|
||||||
|
app.directive('BarBaz', {
|
||||||
|
mounted: spy2
|
||||||
|
})
|
||||||
|
expect(
|
||||||
|
'Directive "BarBaz" has already been registered in target app.'
|
||||||
|
).toHaveBeenWarnedTimes(1)
|
||||||
|
|
||||||
const root = nodeOps.createElement('div')
|
const root = nodeOps.createElement('div')
|
||||||
app.mount(Root, root)
|
app.mount(root)
|
||||||
expect(spy1).toHaveBeenCalled()
|
expect(spy1).toHaveBeenCalled()
|
||||||
expect(spy2).not.toHaveBeenCalled()
|
expect(spy2).not.toHaveBeenCalled()
|
||||||
expect(spy3).toHaveBeenCalled()
|
expect(spy3).toHaveBeenCalled()
|
||||||
@ -232,7 +232,7 @@ describe('api: createApp', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const app = createApp()
|
const app = createApp(Comp)
|
||||||
app.mixin(mixinA)
|
app.mixin(mixinA)
|
||||||
app.mixin(mixinB)
|
app.mixin(mixinB)
|
||||||
|
|
||||||
@ -246,7 +246,7 @@ describe('api: createApp', () => {
|
|||||||
).toHaveBeenWarnedTimes(1)
|
).toHaveBeenWarnedTimes(1)
|
||||||
|
|
||||||
const root = nodeOps.createElement('div')
|
const root = nodeOps.createElement('div')
|
||||||
app.mount(Comp, root)
|
app.mount(root)
|
||||||
|
|
||||||
expect(serializeInner(root)).toBe(`123`)
|
expect(serializeInner(root)).toBe(`123`)
|
||||||
expect(calls).toEqual([
|
expect(calls).toEqual([
|
||||||
@ -272,11 +272,6 @@ describe('api: createApp', () => {
|
|||||||
}
|
}
|
||||||
const PluginD: any = undefined
|
const PluginD: any = undefined
|
||||||
|
|
||||||
const app = createApp()
|
|
||||||
app.use(PluginA)
|
|
||||||
app.use(PluginB, 1, 1)
|
|
||||||
app.use(PluginC)
|
|
||||||
|
|
||||||
const Root = {
|
const Root = {
|
||||||
setup() {
|
setup() {
|
||||||
const foo = inject('foo')
|
const foo = inject('foo')
|
||||||
@ -284,8 +279,14 @@ describe('api: createApp', () => {
|
|||||||
return () => `${foo},${bar}`
|
return () => `${foo},${bar}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const app = createApp(Root)
|
||||||
|
app.use(PluginA)
|
||||||
|
app.use(PluginB, 1, 1)
|
||||||
|
app.use(PluginC)
|
||||||
|
|
||||||
const root = nodeOps.createElement('div')
|
const root = nodeOps.createElement('div')
|
||||||
app.mount(Root, root)
|
app.mount(root)
|
||||||
expect(serializeInner(root)).toBe(`1,2`)
|
expect(serializeInner(root)).toBe(`1,2`)
|
||||||
|
|
||||||
app.use(PluginA)
|
app.use(PluginA)
|
||||||
@ -301,18 +302,14 @@ describe('api: createApp', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
test('config.errorHandler', () => {
|
test('config.errorHandler', () => {
|
||||||
const app = createApp()
|
|
||||||
|
|
||||||
const error = new Error()
|
const error = new Error()
|
||||||
const count = ref(0)
|
const count = ref(0)
|
||||||
|
|
||||||
const handler = (app.config.errorHandler = jest.fn(
|
const handler = jest.fn((err, instance, info) => {
|
||||||
(err, instance, info) => {
|
expect(err).toBe(error)
|
||||||
expect(err).toBe(error)
|
expect((instance as any).count).toBe(count.value)
|
||||||
expect((instance as any).count).toBe(count.value)
|
expect(info).toBe(`render function`)
|
||||||
expect(info).toBe(`render function`)
|
})
|
||||||
}
|
|
||||||
))
|
|
||||||
|
|
||||||
const Root = {
|
const Root = {
|
||||||
setup() {
|
setup() {
|
||||||
@ -326,21 +323,19 @@ describe('api: createApp', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
app.mount(Root, nodeOps.createElement('div'))
|
const app = createApp(Root)
|
||||||
|
app.config.errorHandler = handler
|
||||||
|
app.mount(nodeOps.createElement('div'))
|
||||||
expect(handler).toHaveBeenCalled()
|
expect(handler).toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
test('config.warnHandler', () => {
|
test('config.warnHandler', () => {
|
||||||
const app = createApp()
|
|
||||||
let ctx: any
|
let ctx: any
|
||||||
|
const handler = jest.fn((msg, instance, trace) => {
|
||||||
const handler = (app.config.warnHandler = jest.fn(
|
expect(msg).toMatch(`Component is missing template or render function`)
|
||||||
(msg, instance, trace) => {
|
expect(instance).toBe(ctx.proxy)
|
||||||
expect(msg).toMatch(`Component is missing template or render function`)
|
expect(trace).toMatch(`Hello`)
|
||||||
expect(instance).toBe(ctx.proxy)
|
})
|
||||||
expect(trace).toMatch(`Hello`)
|
|
||||||
}
|
|
||||||
))
|
|
||||||
|
|
||||||
const Root = {
|
const Root = {
|
||||||
name: 'Hello',
|
name: 'Hello',
|
||||||
@ -349,7 +344,9 @@ describe('api: createApp', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
app.mount(Root, nodeOps.createElement('div'))
|
const app = createApp(Root)
|
||||||
|
app.config.warnHandler = handler
|
||||||
|
app.mount(nodeOps.createElement('div'))
|
||||||
expect(handler).toHaveBeenCalledTimes(1)
|
expect(handler).toHaveBeenCalledTimes(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -357,104 +354,82 @@ describe('api: createApp', () => {
|
|||||||
const isNativeTag = jest.fn(tag => tag === 'div')
|
const isNativeTag = jest.fn(tag => tag === 'div')
|
||||||
|
|
||||||
test('Component.name', () => {
|
test('Component.name', () => {
|
||||||
const app = createApp()
|
|
||||||
Object.defineProperty(app.config, 'isNativeTag', {
|
|
||||||
value: isNativeTag,
|
|
||||||
writable: false
|
|
||||||
})
|
|
||||||
|
|
||||||
const Root = {
|
const Root = {
|
||||||
name: 'div',
|
name: 'div',
|
||||||
setup() {
|
|
||||||
return {
|
|
||||||
count: ref(0)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
render() {
|
render() {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
app.mount(Root, nodeOps.createElement('div'))
|
const app = createApp(Root)
|
||||||
|
|
||||||
|
Object.defineProperty(app.config, 'isNativeTag', {
|
||||||
|
value: isNativeTag,
|
||||||
|
writable: false
|
||||||
|
})
|
||||||
|
|
||||||
|
app.mount(nodeOps.createElement('div'))
|
||||||
expect(
|
expect(
|
||||||
`Do not use built-in or reserved HTML elements as component id: div`
|
`Do not use built-in or reserved HTML elements as component id: div`
|
||||||
).toHaveBeenWarned()
|
).toHaveBeenWarned()
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Component.components', () => {
|
test('Component.components', () => {
|
||||||
const app = createApp()
|
|
||||||
Object.defineProperty(app.config, 'isNativeTag', {
|
|
||||||
value: isNativeTag,
|
|
||||||
writable: false
|
|
||||||
})
|
|
||||||
|
|
||||||
const Root = {
|
const Root = {
|
||||||
components: {
|
components: {
|
||||||
div: () => 'div'
|
div: () => 'div'
|
||||||
},
|
},
|
||||||
setup() {
|
|
||||||
return {
|
|
||||||
count: ref(0)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
render() {
|
render() {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
app.mount(Root, nodeOps.createElement('div'))
|
const app = createApp(Root)
|
||||||
|
Object.defineProperty(app.config, 'isNativeTag', {
|
||||||
|
value: isNativeTag,
|
||||||
|
writable: false
|
||||||
|
})
|
||||||
|
|
||||||
|
app.mount(nodeOps.createElement('div'))
|
||||||
expect(
|
expect(
|
||||||
`Do not use built-in or reserved HTML elements as component id: div`
|
`Do not use built-in or reserved HTML elements as component id: div`
|
||||||
).toHaveBeenWarned()
|
).toHaveBeenWarned()
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Component.directives', () => {
|
test('Component.directives', () => {
|
||||||
const app = createApp()
|
|
||||||
Object.defineProperty(app.config, 'isNativeTag', {
|
|
||||||
value: isNativeTag,
|
|
||||||
writable: false
|
|
||||||
})
|
|
||||||
|
|
||||||
const Root = {
|
const Root = {
|
||||||
directives: {
|
directives: {
|
||||||
bind: () => {}
|
bind: () => {}
|
||||||
},
|
},
|
||||||
setup() {
|
|
||||||
return {
|
|
||||||
count: ref(0)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
render() {
|
render() {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
app.mount(Root, nodeOps.createElement('div'))
|
const app = createApp(Root)
|
||||||
|
Object.defineProperty(app.config, 'isNativeTag', {
|
||||||
|
value: isNativeTag,
|
||||||
|
writable: false
|
||||||
|
})
|
||||||
|
|
||||||
|
app.mount(nodeOps.createElement('div'))
|
||||||
expect(
|
expect(
|
||||||
`Do not use built-in directive ids as custom directive id: bind`
|
`Do not use built-in directive ids as custom directive id: bind`
|
||||||
).toHaveBeenWarned()
|
).toHaveBeenWarned()
|
||||||
})
|
})
|
||||||
|
|
||||||
test('register using app.component', () => {
|
test('register using app.component', () => {
|
||||||
const app = createApp()
|
const app = createApp({
|
||||||
|
render() {}
|
||||||
|
})
|
||||||
|
|
||||||
Object.defineProperty(app.config, 'isNativeTag', {
|
Object.defineProperty(app.config, 'isNativeTag', {
|
||||||
value: isNativeTag,
|
value: isNativeTag,
|
||||||
writable: false
|
writable: false
|
||||||
})
|
})
|
||||||
|
|
||||||
const Root = {
|
|
||||||
setup() {
|
|
||||||
return {
|
|
||||||
count: ref(0)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
render() {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
app.component('div', () => 'div')
|
app.component('div', () => 'div')
|
||||||
app.mount(Root, nodeOps.createElement('div'))
|
app.mount(nodeOps.createElement('div'))
|
||||||
expect(
|
expect(
|
||||||
`Do not use built-in or reserved HTML elements as component id: div`
|
`Do not use built-in or reserved HTML elements as component id: div`
|
||||||
).toHaveBeenWarned()
|
).toHaveBeenWarned()
|
@ -1,4 +1,4 @@
|
|||||||
import { createApp, getCurrentInstance, nodeOps } from '@vue/runtime-test'
|
import { h, render, getCurrentInstance, nodeOps } from '@vue/runtime-test'
|
||||||
import { mockWarn } from '@vue/shared'
|
import { mockWarn } from '@vue/shared'
|
||||||
import { ComponentInternalInstance } from '../src/component'
|
import { ComponentInternalInstance } from '../src/component'
|
||||||
|
|
||||||
@ -6,7 +6,6 @@ describe('component: proxy', () => {
|
|||||||
mockWarn()
|
mockWarn()
|
||||||
|
|
||||||
test('data', () => {
|
test('data', () => {
|
||||||
const app = createApp()
|
|
||||||
let instance: ComponentInternalInstance
|
let instance: ComponentInternalInstance
|
||||||
let instanceProxy: any
|
let instanceProxy: any
|
||||||
const Comp = {
|
const Comp = {
|
||||||
@ -23,14 +22,13 @@ describe('component: proxy', () => {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
app.mount(Comp, nodeOps.createElement('div'))
|
render(h(Comp), nodeOps.createElement('div'))
|
||||||
expect(instanceProxy.foo).toBe(1)
|
expect(instanceProxy.foo).toBe(1)
|
||||||
instanceProxy.foo = 2
|
instanceProxy.foo = 2
|
||||||
expect(instance!.data.foo).toBe(2)
|
expect(instance!.data.foo).toBe(2)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('renderContext', () => {
|
test('renderContext', () => {
|
||||||
const app = createApp()
|
|
||||||
let instance: ComponentInternalInstance
|
let instance: ComponentInternalInstance
|
||||||
let instanceProxy: any
|
let instanceProxy: any
|
||||||
const Comp = {
|
const Comp = {
|
||||||
@ -47,14 +45,13 @@ describe('component: proxy', () => {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
app.mount(Comp, nodeOps.createElement('div'))
|
render(h(Comp), nodeOps.createElement('div'))
|
||||||
expect(instanceProxy.foo).toBe(1)
|
expect(instanceProxy.foo).toBe(1)
|
||||||
instanceProxy.foo = 2
|
instanceProxy.foo = 2
|
||||||
expect(instance!.renderContext.foo).toBe(2)
|
expect(instance!.renderContext.foo).toBe(2)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('propsProxy', () => {
|
test('propsProxy', () => {
|
||||||
const app = createApp()
|
|
||||||
let instance: ComponentInternalInstance
|
let instance: ComponentInternalInstance
|
||||||
let instanceProxy: any
|
let instanceProxy: any
|
||||||
const Comp = {
|
const Comp = {
|
||||||
@ -72,7 +69,7 @@ describe('component: proxy', () => {
|
|||||||
instanceProxy = this
|
instanceProxy = this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
app.mount(Comp, nodeOps.createElement('div'))
|
render(h(Comp), nodeOps.createElement('div'))
|
||||||
expect(instanceProxy.foo).toBe(1)
|
expect(instanceProxy.foo).toBe(1)
|
||||||
expect(instance!.propsProxy!.foo).toBe(1)
|
expect(instance!.propsProxy!.foo).toBe(1)
|
||||||
expect(() => (instanceProxy.foo = 2)).toThrow(TypeError)
|
expect(() => (instanceProxy.foo = 2)).toThrow(TypeError)
|
||||||
@ -80,7 +77,6 @@ describe('component: proxy', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
test('public properties', () => {
|
test('public properties', () => {
|
||||||
const app = createApp()
|
|
||||||
let instance: ComponentInternalInstance
|
let instance: ComponentInternalInstance
|
||||||
let instanceProxy: any
|
let instanceProxy: any
|
||||||
const Comp = {
|
const Comp = {
|
||||||
@ -92,7 +88,7 @@ describe('component: proxy', () => {
|
|||||||
instanceProxy = this
|
instanceProxy = this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
app.mount(Comp, nodeOps.createElement('div'))
|
render(h(Comp), nodeOps.createElement('div'))
|
||||||
expect(instanceProxy.$data).toBe(instance!.data)
|
expect(instanceProxy.$data).toBe(instance!.data)
|
||||||
expect(instanceProxy.$props).toBe(instance!.propsProxy)
|
expect(instanceProxy.$props).toBe(instance!.propsProxy)
|
||||||
expect(instanceProxy.$attrs).toBe(instance!.attrs)
|
expect(instanceProxy.$attrs).toBe(instance!.attrs)
|
||||||
@ -108,7 +104,6 @@ describe('component: proxy', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
test('sink', async () => {
|
test('sink', async () => {
|
||||||
const app = createApp()
|
|
||||||
let instance: ComponentInternalInstance
|
let instance: ComponentInternalInstance
|
||||||
let instanceProxy: any
|
let instanceProxy: any
|
||||||
const Comp = {
|
const Comp = {
|
||||||
@ -120,14 +115,13 @@ describe('component: proxy', () => {
|
|||||||
instanceProxy = this
|
instanceProxy = this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
app.mount(Comp, nodeOps.createElement('div'))
|
render(h(Comp), nodeOps.createElement('div'))
|
||||||
instanceProxy.foo = 1
|
instanceProxy.foo = 1
|
||||||
expect(instanceProxy.foo).toBe(1)
|
expect(instanceProxy.foo).toBe(1)
|
||||||
expect(instance!.sink.foo).toBe(1)
|
expect(instance!.sink.foo).toBe(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('has check', () => {
|
test('has check', () => {
|
||||||
const app = createApp()
|
|
||||||
let instanceProxy: any
|
let instanceProxy: any
|
||||||
const Comp = {
|
const Comp = {
|
||||||
render() {},
|
render() {},
|
||||||
@ -148,7 +142,7 @@ describe('component: proxy', () => {
|
|||||||
instanceProxy = this
|
instanceProxy = this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
app.mount(Comp, nodeOps.createElement('div'), { msg: 'hello' })
|
render(h(Comp, { msg: 'hello' }), nodeOps.createElement('div'))
|
||||||
|
|
||||||
// props
|
// props
|
||||||
expect('msg' in instanceProxy).toBe(true)
|
expect('msg' in instanceProxy).toBe(true)
|
||||||
|
@ -12,7 +12,6 @@ import { mockWarn } from '@vue/shared'
|
|||||||
|
|
||||||
describe('resolveAssets', () => {
|
describe('resolveAssets', () => {
|
||||||
test('should work', () => {
|
test('should work', () => {
|
||||||
const app = createApp()
|
|
||||||
const FooBar = () => null
|
const FooBar = () => null
|
||||||
const BarBaz = { mounted: () => null }
|
const BarBaz = { mounted: () => null }
|
||||||
|
|
||||||
@ -49,8 +48,9 @@ describe('resolveAssets', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const app = createApp(Root)
|
||||||
const root = nodeOps.createElement('div')
|
const root = nodeOps.createElement('div')
|
||||||
app.mount(Root, root)
|
app.mount(root)
|
||||||
expect(component1!).toBe(FooBar)
|
expect(component1!).toBe(FooBar)
|
||||||
expect(component2!).toBe(FooBar)
|
expect(component2!).toBe(FooBar)
|
||||||
expect(component3!).toBe(FooBar)
|
expect(component3!).toBe(FooBar)
|
||||||
@ -78,7 +78,6 @@ describe('resolveAssets', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
test('not exist', () => {
|
test('not exist', () => {
|
||||||
const app = createApp()
|
|
||||||
const Root = {
|
const Root = {
|
||||||
setup() {
|
setup() {
|
||||||
resolveComponent('foo')
|
resolveComponent('foo')
|
||||||
@ -87,14 +86,14 @@ describe('resolveAssets', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const app = createApp(Root)
|
||||||
const root = nodeOps.createElement('div')
|
const root = nodeOps.createElement('div')
|
||||||
app.mount(Root, root)
|
app.mount(root)
|
||||||
expect('Failed to resolve component: foo').toHaveBeenWarned()
|
expect('Failed to resolve component: foo').toHaveBeenWarned()
|
||||||
expect('Failed to resolve directive: bar').toHaveBeenWarned()
|
expect('Failed to resolve directive: bar').toHaveBeenWarned()
|
||||||
})
|
})
|
||||||
|
|
||||||
test('resolve dynamic component', () => {
|
test('resolve dynamic component', () => {
|
||||||
const app = createApp()
|
|
||||||
const dynamicComponents = {
|
const dynamicComponents = {
|
||||||
foo: () => 'foo',
|
foo: () => 'foo',
|
||||||
bar: () => 'bar',
|
bar: () => 'bar',
|
||||||
@ -112,8 +111,10 @@ describe('resolveAssets', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const app = createApp(Root)
|
||||||
const root = nodeOps.createElement('div')
|
const root = nodeOps.createElement('div')
|
||||||
app.mount(Root, root)
|
app.mount(root)
|
||||||
expect(foo).toBe(dynamicComponents.foo)
|
expect(foo).toBe(dynamicComponents.foo)
|
||||||
expect(bar).toBe(dynamicComponents.bar)
|
expect(bar).toBe(dynamicComponents.bar)
|
||||||
expect(baz).toBe(dynamicComponents.baz)
|
expect(baz).toBe(dynamicComponents.baz)
|
||||||
|
@ -16,16 +16,11 @@ export interface App<HostElement = any> {
|
|||||||
component(name: string, component: Component): this
|
component(name: string, component: Component): this
|
||||||
directive(name: string): Directive | undefined
|
directive(name: string): Directive | undefined
|
||||||
directive(name: string, directive: Directive): this
|
directive(name: string, directive: Directive): this
|
||||||
mount(
|
mount(rootContainer: HostElement | string): ComponentPublicInstance
|
||||||
rootComponent:
|
|
||||||
| Component
|
|
||||||
// for compatibility with defineComponent() return types
|
|
||||||
| { new (): ComponentPublicInstance<any, any, any, any, any> },
|
|
||||||
rootContainer: HostElement | string,
|
|
||||||
rootProps?: Data
|
|
||||||
): ComponentPublicInstance
|
|
||||||
unmount(rootContainer: HostElement | string): void
|
unmount(rootContainer: HostElement | string): void
|
||||||
provide<T>(key: InjectionKey<T> | string, value: T): this
|
provide<T>(key: InjectionKey<T> | string, value: T): this
|
||||||
|
rootComponent: Component
|
||||||
|
rootContainer: HostElement | null
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AppConfig {
|
export interface AppConfig {
|
||||||
@ -79,16 +74,30 @@ export function createAppContext(): AppContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type CreateAppFunction<HostElement> = (
|
||||||
|
rootComponent:
|
||||||
|
| Component
|
||||||
|
// for compatibility with defineComponent() return types
|
||||||
|
| { new (): ComponentPublicInstance<any, any, any, any, any> },
|
||||||
|
rootProps?: Data | null
|
||||||
|
) => App<HostElement>
|
||||||
|
|
||||||
export function createAppAPI<HostNode, HostElement>(
|
export function createAppAPI<HostNode, HostElement>(
|
||||||
render: RootRenderFunction<HostNode, HostElement>
|
render: RootRenderFunction<HostNode, HostElement>
|
||||||
): () => App<HostElement> {
|
): CreateAppFunction<HostElement> {
|
||||||
return function createApp(): App {
|
return function createApp(
|
||||||
|
rootComponent: Component,
|
||||||
|
rootProps?: Data | null
|
||||||
|
): App {
|
||||||
const context = createAppContext()
|
const context = createAppContext()
|
||||||
const installedPlugins = new Set()
|
const installedPlugins = new Set()
|
||||||
|
|
||||||
let isMounted = false
|
let isMounted = false
|
||||||
|
|
||||||
const app: App = {
|
const app: App = {
|
||||||
|
rootComponent,
|
||||||
|
rootContainer: null,
|
||||||
|
|
||||||
get config() {
|
get config() {
|
||||||
return context.config
|
return context.config
|
||||||
},
|
},
|
||||||
@ -165,11 +174,7 @@ export function createAppAPI<HostNode, HostElement>(
|
|||||||
return app
|
return app
|
||||||
},
|
},
|
||||||
|
|
||||||
mount(
|
mount(rootContainer: HostElement): any {
|
||||||
rootComponent: Component,
|
|
||||||
rootContainer: HostElement,
|
|
||||||
rootProps?: Data | null
|
|
||||||
): any {
|
|
||||||
if (!isMounted) {
|
if (!isMounted) {
|
||||||
if (rootProps != null && !isObject(rootProps)) {
|
if (rootProps != null && !isObject(rootProps)) {
|
||||||
__DEV__ &&
|
__DEV__ &&
|
||||||
@ -190,6 +195,7 @@ export function createAppAPI<HostNode, HostElement>(
|
|||||||
|
|
||||||
render(vnode, rootContainer)
|
render(vnode, rootContainer)
|
||||||
isMounted = true
|
isMounted = true
|
||||||
|
app.rootContainer = rootContainer
|
||||||
return vnode.component!.proxy
|
return vnode.component!.proxy
|
||||||
} else if (__DEV__) {
|
} else if (__DEV__) {
|
||||||
warn(
|
warn(
|
||||||
@ -198,8 +204,12 @@ export function createAppAPI<HostNode, HostElement>(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
unmount(rootContainer: HostElement) {
|
unmount() {
|
||||||
render(null, rootContainer)
|
if (isMounted) {
|
||||||
|
render(null, app.rootContainer!)
|
||||||
|
} else if (__DEV__) {
|
||||||
|
warn(`Cannot unmount an app that is not mounted.`)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
provide(key, value) {
|
provide(key, value) {
|
||||||
|
@ -99,7 +99,13 @@ export { registerRuntimeCompiler } from './component'
|
|||||||
|
|
||||||
// Types -----------------------------------------------------------------------
|
// Types -----------------------------------------------------------------------
|
||||||
|
|
||||||
export { App, AppConfig, AppContext, Plugin } from './apiCreateApp'
|
export {
|
||||||
|
App,
|
||||||
|
AppConfig,
|
||||||
|
AppContext,
|
||||||
|
Plugin,
|
||||||
|
CreateAppFunction
|
||||||
|
} from './apiCreateApp'
|
||||||
export { VNode, VNodeTypes, VNodeProps } from './vnode'
|
export { VNode, VNodeTypes, VNodeProps } from './vnode'
|
||||||
export {
|
export {
|
||||||
Component,
|
Component,
|
||||||
|
@ -46,7 +46,7 @@ import { ShapeFlags } from './shapeFlags'
|
|||||||
import { pushWarningContext, popWarningContext, warn } from './warning'
|
import { pushWarningContext, popWarningContext, warn } from './warning'
|
||||||
import { invokeDirectiveHook } from './directives'
|
import { invokeDirectiveHook } from './directives'
|
||||||
import { ComponentPublicInstance } from './componentProxy'
|
import { ComponentPublicInstance } from './componentProxy'
|
||||||
import { App, createAppAPI } from './apiCreateApp'
|
import { createAppAPI, CreateAppFunction } from './apiCreateApp'
|
||||||
import {
|
import {
|
||||||
SuspenseBoundary,
|
SuspenseBoundary,
|
||||||
queueEffectWithSuspense,
|
queueEffectWithSuspense,
|
||||||
@ -174,7 +174,7 @@ export function createRenderer<
|
|||||||
options: RendererOptions<HostNode, HostElement>
|
options: RendererOptions<HostNode, HostElement>
|
||||||
): {
|
): {
|
||||||
render: RootRenderFunction<HostNode, HostElement>
|
render: RootRenderFunction<HostNode, HostElement>
|
||||||
createApp: () => App<HostElement>
|
createApp: CreateAppFunction<HostElement>
|
||||||
} {
|
} {
|
||||||
type HostVNode = VNode<HostNode, HostElement>
|
type HostVNode = VNode<HostNode, HostElement>
|
||||||
type HostVNodeChildren = VNodeChildren<HostNode, HostElement>
|
type HostVNodeChildren = VNodeChildren<HostNode, HostElement>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
createApp,
|
|
||||||
h,
|
h,
|
||||||
|
render,
|
||||||
nextTick,
|
nextTick,
|
||||||
defineComponent,
|
defineComponent,
|
||||||
vModelDynamic,
|
vModelDynamic,
|
||||||
@ -20,10 +20,9 @@ const setValue = function(this: any, value: any) {
|
|||||||
this.value = value
|
this.value = value
|
||||||
}
|
}
|
||||||
|
|
||||||
let app: any, root: any
|
let root: any
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
app = createApp()
|
|
||||||
root = document.createElement('div') as any
|
root = document.createElement('div') as any
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -44,9 +43,9 @@ describe('vModel', () => {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
app.mount(component, root)
|
render(h(component), root)
|
||||||
|
|
||||||
const input = root.querySelector('input')
|
const input = root.querySelector('input')!
|
||||||
const data = root._vnode.component.data
|
const data = root._vnode.component.data
|
||||||
|
|
||||||
input.value = 'foo'
|
input.value = 'foo'
|
||||||
@ -75,7 +74,7 @@ describe('vModel', () => {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
app.mount(component, root)
|
render(h(component), root)
|
||||||
|
|
||||||
const input = root.querySelector('textarea')
|
const input = root.querySelector('textarea')
|
||||||
const data = root._vnode.component.data
|
const data = root._vnode.component.data
|
||||||
@ -136,7 +135,7 @@ describe('vModel', () => {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
app.mount(component, root)
|
render(h(component), root)
|
||||||
|
|
||||||
const number = root.querySelector('.number')
|
const number = root.querySelector('.number')
|
||||||
const trim = root.querySelector('.trim')
|
const trim = root.querySelector('.trim')
|
||||||
@ -176,7 +175,7 @@ describe('vModel', () => {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
app.mount(component, root)
|
render(h(component), root)
|
||||||
|
|
||||||
const input = root.querySelector('input')
|
const input = root.querySelector('input')
|
||||||
const data = root._vnode.component.data
|
const data = root._vnode.component.data
|
||||||
@ -219,7 +218,7 @@ describe('vModel', () => {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
app.mount(component, root)
|
render(h(component), root)
|
||||||
|
|
||||||
const input = root.querySelector('input')
|
const input = root.querySelector('input')
|
||||||
const data = root._vnode.component.data
|
const data = root._vnode.component.data
|
||||||
@ -262,7 +261,7 @@ describe('vModel', () => {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
app.mount(component, root)
|
render(h(component), root)
|
||||||
|
|
||||||
const input = root.querySelector('input')
|
const input = root.querySelector('input')
|
||||||
const data = root._vnode.component.data
|
const data = root._vnode.component.data
|
||||||
@ -314,7 +313,7 @@ describe('vModel', () => {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
app.mount(component, root)
|
render(h(component), root)
|
||||||
|
|
||||||
const foo = root.querySelector('.foo')
|
const foo = root.querySelector('.foo')
|
||||||
const bar = root.querySelector('.bar')
|
const bar = root.querySelector('.bar')
|
||||||
@ -384,7 +383,7 @@ describe('vModel', () => {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
app.mount(component, root)
|
render(h(component), root)
|
||||||
|
|
||||||
const foo = root.querySelector('.foo')
|
const foo = root.querySelector('.foo')
|
||||||
const bar = root.querySelector('.bar')
|
const bar = root.querySelector('.bar')
|
||||||
@ -437,7 +436,7 @@ describe('vModel', () => {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
app.mount(component, root)
|
render(h(component), root)
|
||||||
|
|
||||||
const input = root.querySelector('select')
|
const input = root.querySelector('select')
|
||||||
const foo = root.querySelector('option[value=foo]')
|
const foo = root.querySelector('option[value=foo]')
|
||||||
@ -494,7 +493,7 @@ describe('vModel', () => {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
app.mount(component, root)
|
render(h(component), root)
|
||||||
|
|
||||||
const input = root.querySelector('select')
|
const input = root.querySelector('select')
|
||||||
const foo = root.querySelector('option[value=foo]')
|
const foo = root.querySelector('option[value=foo]')
|
||||||
|
@ -5,16 +5,15 @@ import {
|
|||||||
nextTick,
|
nextTick,
|
||||||
VNode
|
VNode
|
||||||
} from '@vue/runtime-core'
|
} from '@vue/runtime-core'
|
||||||
import { createApp, vShow } from '@vue/runtime-dom'
|
import { render, vShow } from '@vue/runtime-dom'
|
||||||
|
|
||||||
const withVShow = (node: VNode, exp: any) =>
|
const withVShow = (node: VNode, exp: any) =>
|
||||||
withDirectives(node, [[vShow, exp]])
|
withDirectives(node, [[vShow, exp]])
|
||||||
|
|
||||||
let app: any, root: any
|
let root: any
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
app = createApp()
|
root = document.createElement('div')
|
||||||
root = document.createElement('div') as any
|
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('runtime-dom: v-show directive', () => {
|
describe('runtime-dom: v-show directive', () => {
|
||||||
@ -27,7 +26,7 @@ describe('runtime-dom: v-show directive', () => {
|
|||||||
return [withVShow(h('div'), this.value)]
|
return [withVShow(h('div'), this.value)]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
app.mount(component, root)
|
render(h(component), root)
|
||||||
|
|
||||||
const $div = root.querySelector('div')
|
const $div = root.querySelector('div')
|
||||||
|
|
||||||
@ -43,7 +42,7 @@ describe('runtime-dom: v-show directive', () => {
|
|||||||
return [withVShow(h('div'), this.value)]
|
return [withVShow(h('div'), this.value)]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
app.mount(component, root)
|
render(h(component), root)
|
||||||
|
|
||||||
const $div = root.querySelector('div')
|
const $div = root.querySelector('div')
|
||||||
|
|
||||||
@ -59,7 +58,7 @@ describe('runtime-dom: v-show directive', () => {
|
|||||||
return [withVShow(h('div'), this.value)]
|
return [withVShow(h('div'), this.value)]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
app.mount(component, root)
|
render(h(component), root)
|
||||||
|
|
||||||
const $div = root.querySelector('div')
|
const $div = root.querySelector('div')
|
||||||
const data = root._vnode.component.data
|
const data = root._vnode.component.data
|
||||||
@ -110,7 +109,7 @@ describe('runtime-dom: v-show directive', () => {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
app.mount(component, root)
|
render(h(component), root)
|
||||||
|
|
||||||
const $div = root.querySelector('div')
|
const $div = root.querySelector('div')
|
||||||
const data = root._vnode.component.data
|
const data = root._vnode.component.data
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import {
|
import {
|
||||||
createRenderer,
|
createRenderer,
|
||||||
warn,
|
warn,
|
||||||
App,
|
RootRenderFunction,
|
||||||
RootRenderFunction
|
CreateAppFunction
|
||||||
} from '@vue/runtime-core'
|
} from '@vue/runtime-core'
|
||||||
import { nodeOps } from './nodeOps'
|
import { nodeOps } from './nodeOps'
|
||||||
import { patchProp } from './patchProp'
|
import { patchProp } from './patchProp'
|
||||||
@ -17,8 +17,8 @@ const { render: baseRender, createApp: baseCreateApp } = createRenderer({
|
|||||||
// use explicit type casts here to avoid import() calls in rolled-up d.ts
|
// use explicit type casts here to avoid import() calls in rolled-up d.ts
|
||||||
export const render = baseRender as RootRenderFunction<Node, Element>
|
export const render = baseRender as RootRenderFunction<Node, Element>
|
||||||
|
|
||||||
export const createApp = (): App<Element> => {
|
export const createApp: CreateAppFunction<Element> = (...args) => {
|
||||||
const app = baseCreateApp()
|
const app = baseCreateApp(...args)
|
||||||
|
|
||||||
if (__DEV__) {
|
if (__DEV__) {
|
||||||
// Inject `isNativeTag`
|
// Inject `isNativeTag`
|
||||||
@ -29,8 +29,8 @@ export const createApp = (): App<Element> => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const { mount, unmount } = app
|
const { mount } = app
|
||||||
app.mount = (component, container, props): any => {
|
app.mount = (container): any => {
|
||||||
if (isString(container)) {
|
if (isString(container)) {
|
||||||
container = document.querySelector(container)!
|
container = document.querySelector(container)!
|
||||||
if (!container) {
|
if (!container) {
|
||||||
@ -39,6 +39,7 @@ export const createApp = (): App<Element> => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const component = app.rootComponent
|
||||||
if (
|
if (
|
||||||
__RUNTIME_COMPILE__ &&
|
__RUNTIME_COMPILE__ &&
|
||||||
!isFunction(component) &&
|
!isFunction(component) &&
|
||||||
@ -49,19 +50,7 @@ export const createApp = (): App<Element> => {
|
|||||||
}
|
}
|
||||||
// clear content before mounting
|
// clear content before mounting
|
||||||
container.innerHTML = ''
|
container.innerHTML = ''
|
||||||
return mount(component, container, props)
|
return mount(container)
|
||||||
}
|
|
||||||
|
|
||||||
app.unmount = container => {
|
|
||||||
if (isString(container)) {
|
|
||||||
container = document.querySelector(container)!
|
|
||||||
if (!container) {
|
|
||||||
__DEV__ &&
|
|
||||||
warn(`Failed to unmount app: mount target selector returned null.`)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unmount(container)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return app
|
return app
|
||||||
|
@ -2,7 +2,7 @@ import {
|
|||||||
createRenderer,
|
createRenderer,
|
||||||
VNode,
|
VNode,
|
||||||
RootRenderFunction,
|
RootRenderFunction,
|
||||||
App
|
CreateAppFunction
|
||||||
} from '@vue/runtime-core'
|
} from '@vue/runtime-core'
|
||||||
import { nodeOps, TestNode, TestElement } from './nodeOps'
|
import { nodeOps, TestNode, TestElement } from './nodeOps'
|
||||||
import { patchProp } from './patchProp'
|
import { patchProp } from './patchProp'
|
||||||
@ -14,7 +14,7 @@ const { render: baseRender, createApp: baseCreateApp } = createRenderer({
|
|||||||
})
|
})
|
||||||
|
|
||||||
export const render = baseRender as RootRenderFunction<TestNode, TestElement>
|
export const render = baseRender as RootRenderFunction<TestNode, TestElement>
|
||||||
export const createApp = baseCreateApp as () => App<TestElement>
|
export const createApp = baseCreateApp as CreateAppFunction<TestElement>
|
||||||
|
|
||||||
// convenience for one-off render validations
|
// convenience for one-off render validations
|
||||||
export function renderToString(vnode: VNode) {
|
export function renderToString(vnode: VNode) {
|
||||||
|
@ -14,7 +14,7 @@ describe('compiler + runtime integration', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
createApp().mount(App, container)
|
createApp(App).mount(container)
|
||||||
expect(container.innerHTML).toBe(`0`)
|
expect(container.innerHTML).toBe(`0`)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ describe('compiler + runtime integration', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
createApp().mount(App, container)
|
createApp(App).mount(container)
|
||||||
expect(container.innerHTML).toBe(`0`)
|
expect(container.innerHTML).toBe(`0`)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ describe('compiler + runtime integration', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
createApp().mount(App, container)
|
createApp(App).mount(container)
|
||||||
expect(container.innerHTML).toBe(`0`)
|
expect(container.innerHTML).toBe(`0`)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ describe('compiler + runtime integration', () => {
|
|||||||
const App = {
|
const App = {
|
||||||
template: `<div v-if>`
|
template: `<div v-if>`
|
||||||
}
|
}
|
||||||
createApp().mount(App, container)
|
createApp(App).mount(container)
|
||||||
expect(
|
expect(
|
||||||
`Template compilation error: Element is missing end tag`
|
`Template compilation error: Element is missing end tag`
|
||||||
).toHaveBeenWarned()
|
).toHaveBeenWarned()
|
||||||
@ -78,26 +78,24 @@ describe('compiler + runtime integration', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('should support custom element', () => {
|
it('should support custom element', () => {
|
||||||
const app = createApp()
|
const app = createApp({
|
||||||
const container = document.createElement('div')
|
|
||||||
const App = {
|
|
||||||
template: '<custom></custom>'
|
template: '<custom></custom>'
|
||||||
}
|
})
|
||||||
|
const container = document.createElement('div')
|
||||||
app.config.isCustomElement = tag => tag === 'custom'
|
app.config.isCustomElement = tag => tag === 'custom'
|
||||||
app.mount(App, container)
|
app.mount(container)
|
||||||
expect(container.innerHTML).toBe('<custom></custom>')
|
expect(container.innerHTML).toBe('<custom></custom>')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support using element innerHTML as template', () => {
|
it('should support using element innerHTML as template', () => {
|
||||||
const app = createApp()
|
const app = createApp({
|
||||||
const container = document.createElement('div')
|
|
||||||
container.innerHTML = '{{msg}}'
|
|
||||||
const App = {
|
|
||||||
data: {
|
data: {
|
||||||
msg: 'hello'
|
msg: 'hello'
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
app.mount(App, container)
|
const container = document.createElement('div')
|
||||||
|
container.innerHTML = '{{msg}}'
|
||||||
|
app.mount(container)
|
||||||
expect(container.innerHTML).toBe('hello')
|
expect(container.innerHTML).toBe('hello')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -24,12 +24,12 @@
|
|||||||
<script>
|
<script>
|
||||||
const API_URL = `https://api.github.com/repos/vuejs/vue-next/commits?per_page=3&sha=`
|
const API_URL = `https://api.github.com/repos/vuejs/vue-next/commits?per_page=3&sha=`
|
||||||
|
|
||||||
const App = {
|
Vue.createApp({
|
||||||
data: {
|
data: () => ({
|
||||||
branches: ['master', 'sync'],
|
branches: ['master', 'sync'],
|
||||||
currentBranch: 'master',
|
currentBranch: 'master',
|
||||||
commits: null
|
commits: null
|
||||||
},
|
}),
|
||||||
|
|
||||||
created() {
|
created() {
|
||||||
this.fetchData()
|
this.fetchData()
|
||||||
@ -55,9 +55,7 @@ const App = {
|
|||||||
return v.replace(/T|Z/g, ' ')
|
return v.replace(/T|Z/g, ' ')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}).mount('#demo')
|
||||||
|
|
||||||
Vue.createApp().mount(App, '#demo')
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -87,11 +87,11 @@ const DemoGrid = {
|
|||||||
</div>
|
</div>
|
||||||
<!-- App script -->
|
<!-- App script -->
|
||||||
<script>
|
<script>
|
||||||
const App = {
|
Vue.createApp({
|
||||||
components: {
|
components: {
|
||||||
DemoGrid
|
DemoGrid
|
||||||
},
|
},
|
||||||
data: {
|
data: () => ({
|
||||||
searchQuery: '',
|
searchQuery: '',
|
||||||
gridColumns: ['name', 'power'],
|
gridColumns: ['name', 'power'],
|
||||||
gridData: [
|
gridData: [
|
||||||
@ -100,10 +100,8 @@ const App = {
|
|||||||
{ name: 'Jackie Chan', power: 7000 },
|
{ name: 'Jackie Chan', power: 7000 },
|
||||||
{ name: 'Jet Li', power: 8000 }
|
{ name: 'Jet Li', power: 8000 }
|
||||||
]
|
]
|
||||||
}
|
})
|
||||||
}
|
}).mount('#demo')
|
||||||
|
|
||||||
Vue.createApp().mount(App, '#demo')
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -10,10 +10,10 @@
|
|||||||
<script>
|
<script>
|
||||||
const delay = window.location.hash === '#test' ? 16 : 300
|
const delay = window.location.hash === '#test' ? 16 : 300
|
||||||
|
|
||||||
const App = {
|
Vue.createApp({
|
||||||
data: {
|
data: () => ({
|
||||||
input: '# hello'
|
input: '# hello'
|
||||||
},
|
}),
|
||||||
computed: {
|
computed: {
|
||||||
compiledMarkdown() {
|
compiledMarkdown() {
|
||||||
return marked(this.input, { sanitize: true })
|
return marked(this.input, { sanitize: true })
|
||||||
@ -24,9 +24,7 @@ const App = {
|
|||||||
this.input = e.target.value
|
this.input = e.target.value
|
||||||
}, delay)
|
}, delay)
|
||||||
}
|
}
|
||||||
}
|
}).mount('#editor')
|
||||||
|
|
||||||
Vue.createApp().mount(App, '#editor')
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -97,14 +97,15 @@ const globalStats = [
|
|||||||
{ label: 'E', value: 100 },
|
{ label: 'E', value: 100 },
|
||||||
{ label: 'F', value: 100 }
|
{ label: 'F', value: 100 }
|
||||||
]
|
]
|
||||||
const App = {
|
|
||||||
|
Vue.createApp({
|
||||||
components: {
|
components: {
|
||||||
Polygraph
|
Polygraph
|
||||||
},
|
},
|
||||||
data: {
|
data: () => ({
|
||||||
newLabel: '',
|
newLabel: '',
|
||||||
stats: globalStats
|
stats: globalStats
|
||||||
},
|
}),
|
||||||
methods: {
|
methods: {
|
||||||
add(e) {
|
add(e) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
@ -123,9 +124,7 @@ const App = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}).mount('#demo')
|
||||||
|
|
||||||
Vue.createApp().mount(App, '#demo')
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -82,14 +82,14 @@ const filters = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const App = {
|
Vue.createApp({
|
||||||
// app initial state
|
// app initial state
|
||||||
data: {
|
data: () => ({
|
||||||
todos: todoStorage.fetch(),
|
todos: todoStorage.fetch(),
|
||||||
newTodo: '',
|
newTodo: '',
|
||||||
editedTodo: null,
|
editedTodo: null,
|
||||||
visibility: 'all'
|
visibility: 'all'
|
||||||
},
|
}),
|
||||||
|
|
||||||
// watch todos change for localStorage persistence
|
// watch todos change for localStorage persistence
|
||||||
watch: {
|
watch: {
|
||||||
@ -192,7 +192,5 @@ const App = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}).mount('#app')
|
||||||
|
|
||||||
Vue.createApp().mount(App, '#app')
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -69,43 +69,43 @@ const TreeItem = {
|
|||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const App = {
|
const treeData = {
|
||||||
components: {
|
name: 'My Tree',
|
||||||
TreeItem
|
children: [
|
||||||
},
|
{ name: 'hello' },
|
||||||
data: {
|
{ name: 'wat' },
|
||||||
treeData: {
|
{
|
||||||
name: 'My Tree',
|
name: 'child folder',
|
||||||
children: [
|
children: [
|
||||||
|
{
|
||||||
|
name: 'child folder',
|
||||||
|
children: [
|
||||||
|
{ name: 'hello' },
|
||||||
|
{ name: 'wat' }
|
||||||
|
]
|
||||||
|
},
|
||||||
{ name: 'hello' },
|
{ name: 'hello' },
|
||||||
{ name: 'wat' },
|
{ name: 'wat' },
|
||||||
{
|
{
|
||||||
name: 'child folder',
|
name: 'child folder',
|
||||||
children: [
|
children: [
|
||||||
{
|
|
||||||
name: 'child folder',
|
|
||||||
children: [
|
|
||||||
{ name: 'hello' },
|
|
||||||
{ name: 'wat' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{ name: 'hello' },
|
{ name: 'hello' },
|
||||||
{ name: 'wat' },
|
{ name: 'wat' }
|
||||||
{
|
|
||||||
name: 'child folder',
|
|
||||||
children: [
|
|
||||||
{ name: 'hello' },
|
|
||||||
{ name: 'wat' }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
Vue.createApp().mount(App, '#demo')
|
Vue.createApp({
|
||||||
|
components: {
|
||||||
|
TreeItem
|
||||||
|
},
|
||||||
|
data: () => ({
|
||||||
|
treeData
|
||||||
|
})
|
||||||
|
}).mount('#demo')
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -32,7 +32,7 @@ const truncate = v => {
|
|||||||
|
|
||||||
const formatDate = v => v.replace(/T|Z/g, ' ')
|
const formatDate = v => v.replace(/T|Z/g, ' ')
|
||||||
|
|
||||||
const App = {
|
createApp({
|
||||||
setup() {
|
setup() {
|
||||||
const currentBranch = ref('master')
|
const currentBranch = ref('master')
|
||||||
const commits = ref(null)
|
const commits = ref(null)
|
||||||
@ -54,9 +54,7 @@ const App = {
|
|||||||
formatDate
|
formatDate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}).mount('#demo')
|
||||||
|
|
||||||
createApp().mount(App, '#demo')
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -93,11 +93,11 @@ const DemoGrid = {
|
|||||||
</div>
|
</div>
|
||||||
<!-- App script -->
|
<!-- App script -->
|
||||||
<script>
|
<script>
|
||||||
const App = {
|
Vue.createApp({
|
||||||
components: {
|
components: {
|
||||||
DemoGrid
|
DemoGrid
|
||||||
},
|
},
|
||||||
data: {
|
data: () => ({
|
||||||
searchQuery: '',
|
searchQuery: '',
|
||||||
gridColumns: ['name', 'power'],
|
gridColumns: ['name', 'power'],
|
||||||
gridData: [
|
gridData: [
|
||||||
@ -106,10 +106,8 @@ const App = {
|
|||||||
{ name: 'Jackie Chan', power: 7000 },
|
{ name: 'Jackie Chan', power: 7000 },
|
||||||
{ name: 'Jet Li', power: 8000 }
|
{ name: 'Jet Li', power: 8000 }
|
||||||
]
|
]
|
||||||
}
|
})
|
||||||
}
|
}).mount('#demo')
|
||||||
|
|
||||||
Vue.createApp().mount(App, '#demo')
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
const delay = window.location.hash === '#test' ? 16 : 300
|
const delay = window.location.hash === '#test' ? 16 : 300
|
||||||
const { ref, computed } = Vue
|
const { ref, computed } = Vue
|
||||||
|
|
||||||
const App = {
|
Vue.createApp({
|
||||||
setup() {
|
setup() {
|
||||||
const input = ref('# hello')
|
const input = ref('# hello')
|
||||||
const output = computed(() => marked(input.value, { sanitize: true }))
|
const output = computed(() => marked(input.value, { sanitize: true }))
|
||||||
@ -23,9 +23,7 @@ const App = {
|
|||||||
update
|
update
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}).mount('#editor')
|
||||||
|
|
||||||
Vue.createApp().mount(App, '#editor')
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -100,7 +100,8 @@ const globalStats = [
|
|||||||
{ label: 'E', value: 100 },
|
{ label: 'E', value: 100 },
|
||||||
{ label: 'F', value: 100 }
|
{ label: 'F', value: 100 }
|
||||||
]
|
]
|
||||||
const App = {
|
|
||||||
|
createApp({
|
||||||
components: {
|
components: {
|
||||||
Polygraph
|
Polygraph
|
||||||
},
|
},
|
||||||
@ -133,9 +134,7 @@ const App = {
|
|||||||
remove
|
remove
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}).mount('#demo')
|
||||||
|
|
||||||
createApp().mount(App, '#demo')
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -90,7 +90,7 @@ function pluralize (n) {
|
|||||||
return n === 1 ? 'item' : 'items'
|
return n === 1 ? 'item' : 'items'
|
||||||
}
|
}
|
||||||
|
|
||||||
const App = {
|
createApp({
|
||||||
setup () {
|
setup () {
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
todos: todoStorage.fetch(),
|
todos: todoStorage.fetch(),
|
||||||
@ -202,7 +202,5 @@ const App = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}).mount('#app')
|
||||||
|
|
||||||
createApp().mount(App, '#app')
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -72,43 +72,43 @@ const TreeItem = {
|
|||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const App = {
|
const treeData = {
|
||||||
components: {
|
name: 'My Tree',
|
||||||
TreeItem
|
children: [
|
||||||
},
|
{ name: 'hello' },
|
||||||
data: {
|
{ name: 'wat' },
|
||||||
treeData: {
|
{
|
||||||
name: 'My Tree',
|
name: 'child folder',
|
||||||
children: [
|
children: [
|
||||||
|
{
|
||||||
|
name: 'child folder',
|
||||||
|
children: [
|
||||||
|
{ name: 'hello' },
|
||||||
|
{ name: 'wat' }
|
||||||
|
]
|
||||||
|
},
|
||||||
{ name: 'hello' },
|
{ name: 'hello' },
|
||||||
{ name: 'wat' },
|
{ name: 'wat' },
|
||||||
{
|
{
|
||||||
name: 'child folder',
|
name: 'child folder',
|
||||||
children: [
|
children: [
|
||||||
{
|
|
||||||
name: 'child folder',
|
|
||||||
children: [
|
|
||||||
{ name: 'hello' },
|
|
||||||
{ name: 'wat' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{ name: 'hello' },
|
{ name: 'hello' },
|
||||||
{ name: 'wat' },
|
{ name: 'wat' }
|
||||||
{
|
|
||||||
name: 'child folder',
|
|
||||||
children: [
|
|
||||||
{ name: 'hello' },
|
|
||||||
{ name: 'wat' }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
Vue.createApp().mount(App, '#demo')
|
Vue.createApp({
|
||||||
|
components: {
|
||||||
|
TreeItem
|
||||||
|
},
|
||||||
|
data: () => ({
|
||||||
|
treeData
|
||||||
|
})
|
||||||
|
}).mount('#demo')
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -24,7 +24,7 @@ const Item = {
|
|||||||
template: `<div>{{ msg }} <button @click="$emit('rm')">x</button></div>`
|
template: `<div>{{ msg }} <button @click="$emit('rm')">x</button></div>`
|
||||||
}
|
}
|
||||||
|
|
||||||
const App = {
|
Vue.createApp({
|
||||||
components: {
|
components: {
|
||||||
Item
|
Item
|
||||||
},
|
},
|
||||||
@ -51,9 +51,7 @@ const App = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}).mount('#app')
|
||||||
|
|
||||||
Vue.createApp().mount(App, '#app')
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -56,13 +56,12 @@ const Modal = {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const App = {
|
Vue.createApp({
|
||||||
components: { Modal },
|
components: { Modal },
|
||||||
data: {
|
data: () => ({
|
||||||
showModal: false
|
showModal: false
|
||||||
}
|
})
|
||||||
}
|
}).mount('#app')
|
||||||
Vue.createApp().mount(App, '#app')
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
Loading…
Reference in New Issue
Block a user