diff --git a/packages/runtime-core/__tests__/fragment.spec.ts b/packages/runtime-core/__tests__/fragment.spec.ts index e558a741..0096cc77 100644 --- a/packages/runtime-core/__tests__/fragment.spec.ts +++ b/packages/runtime-core/__tests__/fragment.spec.ts @@ -16,14 +16,14 @@ import { } from '@vue/runtime-test' describe('Fragments', () => { - it('should allow returning multiple component root nodes', () => { + it('should allow returning multiple component root nodes', async () => { class App extends Component { render() { return [h('div', 'one'), 'two'] } } const root = nodeOps.createElement('div') - render(h(App), root) + await render(h(App), root) expect(serialize(root)).toBe(`
one
two
`) expect(root.children.length).toBe(2) expect(root.children[0]).toMatchObject({ @@ -40,14 +40,14 @@ describe('Fragments', () => { }) }) - it('should be able to explicitly create fragments', () => { + it('should be able to explicitly create fragments', async () => { class App extends Component { render() { return h('div', [h(Fragment, [h('div', 'one'), 'two'])]) } } const root = nodeOps.createElement('div') - render(h(App), root) + await render(h(App), root) const parent = root.children[0] as TestElement expect(serialize(parent)).toBe(`
one
two
`) }) @@ -65,7 +65,7 @@ describe('Fragments', () => { } } const root = nodeOps.createElement('div') - render(h(App), root) + await render(h(App), root) expect(serialize(root)).toBe(`
one
two
`) @@ -84,7 +84,7 @@ describe('Fragments', () => { } } const root = nodeOps.createElement('div') - render(h(App), root) + await await render(h(App), root) expect(serialize(root)).toBe(`
one
two
`) @@ -103,7 +103,7 @@ describe('Fragments', () => { } } const root = nodeOps.createElement('div') - render(h(App), root) + await render(h(App), root) expect(serialize(root)).toBe(`
one
two
`) @@ -138,7 +138,7 @@ describe('Fragments', () => { } } const root = nodeOps.createElement('div') - render(h(App), root) + await render(h(App), root) const parent = root.children[0] as TestElement expect(serialize(parent)).toBe( @@ -179,7 +179,7 @@ describe('Fragments', () => { } const root = nodeOps.createElement('div') - render(h(App), root) + await render(h(App), root) expect(serialize(root)).toBe( `
outer
one
two
` diff --git a/packages/runtime-core/src/component.ts b/packages/runtime-core/src/component.ts index e220056b..6de11b64 100644 --- a/packages/runtime-core/src/component.ts +++ b/packages/runtime-core/src/component.ts @@ -109,7 +109,8 @@ export interface ComponentInstance

// actual implementation of the component class InternalComponent implements PublicInstanceMethods { get $el(): any { - return this.$vnode && this.$vnode.el + const el = this.$vnode && this.$vnode.el + return typeof el === 'function' ? (el as any)() : el } $vnode: VNode | null = null diff --git a/packages/runtime-core/src/createRenderer.ts b/packages/runtime-core/src/createRenderer.ts index 3fe1b4d5..a85cffd6 100644 --- a/packages/runtime-core/src/createRenderer.ts +++ b/packages/runtime-core/src/createRenderer.ts @@ -228,13 +228,9 @@ export function createRenderer(options: RendererOptions) { // kept-alive activateComponentInstance(vnode, container, endNode) } else { - if (__JSDOM__) { + queueJob(() => { mountComponentInstance(vnode, container, isSVG, endNode) - } else { - queueJob(() => { - mountComponentInstance(vnode, container, isSVG, endNode) - }, flushHooks) - } + }, flushHooks) } } @@ -1441,7 +1437,6 @@ export function createRenderer(options: RendererOptions) { } } return nextTick(() => { - debugger return vnode && vnode.flags & VNodeFlags.COMPONENT_STATEFUL ? (vnode.children as ComponentInstance).$proxy : null diff --git a/packages/runtime-test/__tests__/testRuntime.spec.ts b/packages/runtime-test/__tests__/testRuntime.spec.ts index 09480465..ad7c421e 100644 --- a/packages/runtime-test/__tests__/testRuntime.spec.ts +++ b/packages/runtime-test/__tests__/testRuntime.spec.ts @@ -17,7 +17,7 @@ import { } from '../src' describe('test renderer', () => { - it('should work', () => { + it('should work', async () => { class App extends Component { render() { return h( @@ -30,7 +30,7 @@ describe('test renderer', () => { } } const root = nodeOps.createElement('div') - render(h(App), root) + await render(h(App), root) expect(root.children.length).toBe(1) @@ -64,7 +64,7 @@ describe('test renderer', () => { const root = nodeOps.createElement('div') resetOps() - render(h(App), root) + await render(h(App), root) const ops = dumpOps() expect(ops.length).toBe(5) @@ -126,7 +126,7 @@ describe('test renderer', () => { }) }) - it('should be able to serialize nodes', () => { + it('should be able to serialize nodes', async () => { class App extends Component { render() { return h( @@ -139,7 +139,7 @@ describe('test renderer', () => { } } const root = nodeOps.createElement('div') - render(h(App), root) + await render(h(App), root) expect(serialize(root)).toEqual( `

foohello
` ) diff --git a/packages/runtime-test/src/nodeOps.ts b/packages/runtime-test/src/nodeOps.ts index 9b4e4846..bcf4e1e4 100644 --- a/packages/runtime-test/src/nodeOps.ts +++ b/packages/runtime-test/src/nodeOps.ts @@ -63,6 +63,9 @@ export function dumpOps(): NodeOp[] { } function createElement(tag: string): TestElement { + if (nodeId === 5) { + throw new Error('foo') + } const node: TestElement = { id: nodeId++, type: NodeTypes.ELEMENT, diff --git a/packages/scheduler/src/experimental.ts b/packages/scheduler/src/experimental.ts index 7c4a0ed5..80a5ccf6 100644 --- a/packages/scheduler/src/experimental.ts +++ b/packages/scheduler/src/experimental.ts @@ -61,7 +61,10 @@ export function nextTick(fn?: () => T): Promise { nextTickQueue.push(() => { resolve(fn ? fn() : undefined) }) - pendingRejectors.push(reject) + pendingRejectors.push(err => { + if (fn) fn() + reject(err) + }) } else { resolve(fn ? fn() : undefined) } diff --git a/packages/scheduler/src/patchNodeOps.ts b/packages/scheduler/src/patchNodeOps.ts index 0ac25cc4..43f18c9d 100644 --- a/packages/scheduler/src/patchNodeOps.ts +++ b/packages/scheduler/src/patchNodeOps.ts @@ -1,5 +1,6 @@ import { NodeOps } from '@vue/runtime-core' import { nodeOps } from '../../runtime-dom/src/nodeOps' +import { nodeOps as testNodeOps } from '../../runtime-test/src/nodeOps' export type Op = [Function, ...any[]] @@ -14,27 +15,32 @@ const evaluate = (v: any) => { } // patch nodeOps to record operations without touching the DOM -Object.keys(nodeOps).forEach((key: keyof NodeOps) => { - const original = nodeOps[key] as Function - if (key === 'querySelector') { - return - } - if (/create/.test(key)) { - nodeOps[key] = (...args: any[]) => { - let res: any - if (currentOps) { - return () => res || (res = original(...args)) - } else { - return original(...args) +function patchOps(nodeOps: NodeOps) { + Object.keys(nodeOps).forEach((key: keyof NodeOps) => { + const original = nodeOps[key] as Function + if (key === 'querySelector') { + return + } + if (/create/.test(key)) { + nodeOps[key] = (...args: any[]) => { + let res: any + if (currentOps) { + return () => res || (res = original(...args)) + } else { + return original(...args) + } + } + } else { + nodeOps[key] = (...args: any[]) => { + if (currentOps) { + currentOps.push([original, ...args.map(evaluate)]) + } else { + original(...args) + } } } - } else { - nodeOps[key] = (...args: any[]) => { - if (currentOps) { - currentOps.push([original, ...args.map(evaluate)]) - } else { - original(...args) - } - } - } -}) + }) +} + +patchOps(nodeOps) +patchOps(testNodeOps)