From f79f0e658b5eec55fb687acdcf6134b4990a90d6 Mon Sep 17 00:00:00 2001 From: Evan You Date: Fri, 2 Nov 2018 14:09:00 +0900 Subject: [PATCH] wip: fix one test --- .../__tests__/parentChain.spec.ts | 15 +- packages/runtime-core/src/createRenderer.ts | 151 +++++++++--------- packages/runtime-core/src/optional/context.ts | 2 - packages/runtime-test/package.json | 4 + packages/scheduler/src/patchNodeOps.ts | 8 +- packages/vue-compat/__tests__/compat.spec.ts | 2 +- 6 files changed, 93 insertions(+), 89 deletions(-) diff --git a/packages/runtime-core/__tests__/parentChain.spec.ts b/packages/runtime-core/__tests__/parentChain.spec.ts index 119b653651..c010c9dfc0 100644 --- a/packages/runtime-core/__tests__/parentChain.spec.ts +++ b/packages/runtime-core/__tests__/parentChain.spec.ts @@ -1,10 +1,9 @@ import { h, Component, - render, - nodeOps, observable, - nextTick + nextTick, + renderInstance } from '@vue/runtime-test' describe('Parent chain management', () => { @@ -36,11 +35,12 @@ describe('Parent chain management', () => { unmounted() { grandChildren.splice(grandChildren.indexOf(this), 1) } - render() {} + render() { + return h('div') + } } - const root = nodeOps.createElement('div') - const parent = (await render(h(Parent), root)) as Component + const parent = await renderInstance(Parent) expect(child.$parent).toBe(parent) expect(child.$root).toBe(parent) @@ -98,8 +98,7 @@ describe('Parent chain management', () => { render() {} } - const root = nodeOps.createElement('div') - const parent = (await render(h(Parent), root)) as Component + const parent = await renderInstance(Parent) expect(child.$parent).toBe(parent) expect(child.$root).toBe(parent) diff --git a/packages/runtime-core/src/createRenderer.ts b/packages/runtime-core/src/createRenderer.ts index a85cffd67e..f8c5c26ea6 100644 --- a/packages/runtime-core/src/createRenderer.ts +++ b/packages/runtime-core/src/createRenderer.ts @@ -7,7 +7,6 @@ import { MountedVNode, RenderNode, createTextVNode, - Ref, VNodeChildren } from './vdom' import { ComponentInstance } from './component' @@ -109,9 +108,13 @@ export function createRenderer(options: RendererOptions) { const lifecycleHooks: Function[] = [] const vnodeUpdatedHooks: Function[] = [] + function queuePostCommitHook(fn: Function) { + lifecycleHooks.push(fn) + } + function flushHooks() { let fn - while ((fn = lifecycleHooks.shift())) { + while ((fn = lifecycleHooks.pop())) { fn() } } @@ -187,21 +190,17 @@ export function createRenderer(options: RendererOptions) { insertOrAppend(container, el, endNode) } if (ref) { - mountRef(ref, el) + queuePostCommitHook(() => { + ref(el) + }) } if (data != null && data.vnodeMounted) { - lifecycleHooks.unshift(() => { + queuePostCommitHook(() => { data.vnodeMounted(vnode) }) } } - function mountRef(ref: Ref, el: RenderNode | ComponentInstance) { - lifecycleHooks.push(() => { - ref(el) - }) - } - function mountComponent( vnode: VNode, container: RenderNode | null, @@ -325,8 +324,10 @@ export function createRenderer(options: RendererOptions) { const { children, childFlags } = vnode switch (childFlags) { case ChildrenFlags.SINGLE_VNODE: + queuePostCommitHook(() => { + vnode.el = (children as MountedVNode).el + }) mount(children as VNode, container, contextVNode, isSVG, endNode) - vnode.el = (children as MountedVNode).el break case ChildrenFlags.NO_CHILDREN: const placeholder = createTextVNode('') @@ -334,6 +335,9 @@ export function createRenderer(options: RendererOptions) { vnode.el = placeholder.el break default: + queuePostCommitHook(() => { + vnode.el = (children as MountedVNode[])[0].el + }) mountArrayChildren( children as VNode[], container, @@ -341,7 +345,6 @@ export function createRenderer(options: RendererOptions) { isSVG, endNode ) - vnode.el = (children as MountedVNode[])[0].el } } @@ -369,7 +372,9 @@ export function createRenderer(options: RendererOptions) { ) } if (ref) { - mountRef(ref, target as RenderNode) + queuePostCommitHook(() => { + ref(target) + }) } const placeholder = createTextVNode('') mountText(placeholder, container, null) @@ -573,6 +578,18 @@ export function createRenderer(options: RendererOptions) { // then retrieve its next sibling to use as the end node for patchChildren. const endNode = platformNextSibling(getVNodeLastEl(prevVNode)) const { childFlags, children } = nextVNode + queuePostCommitHook(() => { + switch (childFlags) { + case ChildrenFlags.SINGLE_VNODE: + nextVNode.el = (children as MountedVNode).el + break + case ChildrenFlags.NO_CHILDREN: + nextVNode.el = prevVNode.el + break + default: + nextVNode.el = (children as MountedVNode[])[0].el + } + }) patchChildren( prevVNode.childFlags, childFlags, @@ -583,16 +600,6 @@ export function createRenderer(options: RendererOptions) { isSVG, endNode ) - switch (childFlags) { - case ChildrenFlags.SINGLE_VNODE: - nextVNode.el = (children as MountedVNode).el - break - case ChildrenFlags.NO_CHILDREN: - nextVNode.el = prevVNode.el - break - default: - nextVNode.el = (children as MountedVNode[])[0].el - } } function getVNodeLastEl(vnode: MountedVNode): RenderNode { @@ -1152,7 +1159,7 @@ export function createRenderer(options: RendererOptions) { container: RenderNode | null, isSVG: boolean, endNode: RenderNode | null - ): RenderNode { + ) { if (__DEV__) { pushWarningContext(vnode) } @@ -1190,6 +1197,20 @@ export function createRenderer(options: RendererOptions) { } else { // this will be executed synchronously right here instance.$vnode = renderInstanceRoot(instance) as MountedVNode + + queuePostCommitHook(() => { + vnode.el = instance.$vnode.el + if (vnode.ref) { + vnode.ref($proxy) + } + // retrieve mounted value after initial render so that we get + // to inject effects in hooks + const { mounted } = instance.$options + if (mounted) { + callLifecycleHookWithHandle(mounted, $proxy, ErrorTypes.MOUNTED) + } + }) + mount( instance.$vnode, container, @@ -1197,7 +1218,6 @@ export function createRenderer(options: RendererOptions) { isSVG, endNode ) - vnode.el = instance.$vnode.el if (__COMPAT__) { // expose __vue__ for devtools @@ -1205,18 +1225,6 @@ export function createRenderer(options: RendererOptions) { } instance._mounted = true - if (vnode.ref) { - mountRef(vnode.ref, $proxy) - } - - // retrieve mounted value right before calling it so that we get - // to inject effects in first render - const { mounted } = instance.$options - if (mounted) { - lifecycleHooks.unshift(() => { - callLifecycleHookWithHandle(mounted, $proxy, ErrorTypes.MOUNTED) - }) - } } }, { @@ -1229,8 +1237,6 @@ export function createRenderer(options: RendererOptions) { if (__DEV__) { popWarningContext() } - - return vnode.el as RenderNode } function updateComponentInstance( @@ -1259,52 +1265,45 @@ export function createRenderer(options: RendererOptions) { const nextVNode = (instance.$vnode = renderInstanceRoot( instance ) as MountedVNode) - const container = platformParentNode(prevVNode.el) as RenderNode - patch(prevVNode, nextVNode, container, $parentVNode as MountedVNode, isSVG) - const el = nextVNode.el as RenderNode - - if (__COMPAT__) { - // expose __vue__ for devtools - ;(el as any).__vue__ = instance - } - // recursively update contextVNode el for nested HOCs - if ((nextVNode.flags & VNodeFlags.PORTAL) === 0) { - let vnode = $parentVNode - while (vnode !== null) { - if ((vnode.flags & VNodeFlags.COMPONENT) > 0) { - vnode.el = el + queuePostCommitHook(() => { + const el = nextVNode.el as RenderNode + if (__COMPAT__) { + // expose __vue__ for devtools + ;(el as any).__vue__ = instance + } + // recursively update contextVNode el for nested HOCs + if ((nextVNode.flags & VNodeFlags.PORTAL) === 0) { + let vnode = $parentVNode + while (vnode !== null) { + if ((vnode.flags & VNodeFlags.COMPONENT) > 0) { + vnode.el = el + } + vnode = vnode.contextVNode } - vnode = vnode.contextVNode } - } - - const { updated } = instance.$options - if (updated) { - // Because the child's update is executed by the scheduler and not - // synchronously within the parent's update call, the child's updated hook - // will be added to the queue AFTER the parent's, but they should be - // invoked BEFORE the parent's. Therefore we add them to the head of the - // queue instead. - lifecycleHooks.unshift(() => { + const { updated } = instance.$options + if (updated) { callLifecycleHookWithHandle( updated, $proxy, ErrorTypes.UPDATED, nextVNode ) - }) - } + } + if (vnodeUpdatedHooks.length > 0) { + const vnodeUpdatedHooksForCurrentInstance = vnodeUpdatedHooks.slice() + vnodeUpdatedHooks.length = 0 + queuePostCommitHook(() => { + for (let i = 0; i < vnodeUpdatedHooksForCurrentInstance.length; i++) { + vnodeUpdatedHooksForCurrentInstance[i]() + } + }) + } + }) - if (vnodeUpdatedHooks.length > 0) { - const vnodeUpdatedHooksForCurrentInstance = vnodeUpdatedHooks.slice() - vnodeUpdatedHooks.length = 0 - lifecycleHooks.unshift(() => { - for (let i = 0; i < vnodeUpdatedHooksForCurrentInstance.length; i++) { - vnodeUpdatedHooksForCurrentInstance[i]() - } - }) - } + const container = platformParentNode(prevVNode.el) as RenderNode + patch(prevVNode, nextVNode, container, $parentVNode as MountedVNode, isSVG) if (__DEV__ && instance.$parentVNode) { popWarningContext() @@ -1357,7 +1356,7 @@ export function createRenderer(options: RendererOptions) { if (__DEV__) { popWarningContext() } - lifecycleHooks.push(() => { + queuePostCommitHook(() => { callActivatedHook(instance, true) }) } diff --git a/packages/runtime-core/src/optional/context.ts b/packages/runtime-core/src/optional/context.ts index 424bc5e07f..c1d5610840 100644 --- a/packages/runtime-core/src/optional/context.ts +++ b/packages/runtime-core/src/optional/context.ts @@ -92,5 +92,3 @@ export const Inject: FunctionalComponent = ( } return slots.default && slots.default(resolvedValue) } - -Inject.pure = true diff --git a/packages/runtime-test/package.json b/packages/runtime-test/package.json index f3414a99f4..4558329718 100644 --- a/packages/runtime-test/package.json +++ b/packages/runtime-test/package.json @@ -9,6 +9,10 @@ "type": "git", "url": "git+https://github.com/vuejs/vue.git" }, + "buildOptions": { + "name": "VueTestRuntime", + "formats": ["esm", "cjs", "global"] + }, "keywords": [ "vue" ], diff --git a/packages/scheduler/src/patchNodeOps.ts b/packages/scheduler/src/patchNodeOps.ts index 43f18c9d52..18b0811a30 100644 --- a/packages/scheduler/src/patchNodeOps.ts +++ b/packages/scheduler/src/patchNodeOps.ts @@ -30,14 +30,18 @@ function patchOps(nodeOps: NodeOps) { return original(...args) } } - } else { + } else if (!/parent|next|query/.test(key)) { nodeOps[key] = (...args: any[]) => { if (currentOps) { currentOps.push([original, ...args.map(evaluate)]) } else { - original(...args) + return original(...args) } } + } else { + nodeOps[key] = (node: any) => { + return original(evaluate(node)) + } } }) } diff --git a/packages/vue-compat/__tests__/compat.spec.ts b/packages/vue-compat/__tests__/compat.spec.ts index b1aa63c26c..9552f743e5 100644 --- a/packages/vue-compat/__tests__/compat.spec.ts +++ b/packages/vue-compat/__tests__/compat.spec.ts @@ -1,6 +1,6 @@ ;(global as any).__COMPAT__ = true -import Vue from '../src/index' +import Vue from '../src/index-compat' describe('2.x compat build', async () => { test('should work', async () => { -- 2.47.3