]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
wip: always track component nodes
authorEvan You <yyx990803@gmail.com>
Fri, 31 May 2019 18:14:49 +0000 (02:14 +0800)
committerEvan You <yyx990803@gmail.com>
Fri, 31 May 2019 18:14:49 +0000 (02:14 +0800)
packages/runtime-core/src/component.ts
packages/runtime-core/src/createRenderer.ts
packages/runtime-core/src/index.ts
packages/runtime-core/src/vnode.ts

index 5ae92c9f105f86957b83e814663c47ce8f0dda1f..d34500818096378f0e66e008b499078a36017076 100644 (file)
@@ -163,7 +163,8 @@ export function renderComponentRoot(instance: ComponentInstance): VNode {
 
 export function shouldUpdateComponent(
   prevVNode: VNode,
-  nextVNode: VNode
+  nextVNode: VNode,
+  optimized?: boolean
 ): boolean {
   const { props: prevProps, children: prevChildren } = prevVNode
   const { props: nextProps, children: nextChildren, patchFlag } = nextVNode
@@ -185,7 +186,7 @@ export function shouldUpdateComponent(
         }
       }
     }
-  } else {
+  } else if (!optimized) {
     // this path is only taken by manually written render functions
     // so presence of any children leads to a forced update
     if (prevChildren != null || nextChildren != null) {
index fa7a6175508b546199f23fdc8f832c9ac7da01fa..636af1155fd4db1290de090b7a338c0105a30077 100644 (file)
@@ -139,7 +139,7 @@ export function createRenderer(options: RendererOptions) {
             // TODO warn invalid node type
             debugger
           }
-          processComponent(n1, n2, container, anchor)
+          processComponent(n1, n2, container, anchor, optimized)
         }
         break
     }
@@ -426,16 +426,18 @@ export function createRenderer(options: RendererOptions) {
     n1: VNode | null,
     n2: VNode,
     container: HostNode,
-    anchor?: HostNode
+    anchor?: HostNode,
+    optimized?: boolean
   ) {
     if (n1 == null) {
       mountComponent(n2, container, anchor)
     } else {
       const instance = (n2.component = n1.component) as ComponentInstance
-      if (shouldUpdateComponent(n1, n2)) {
+      if (shouldUpdateComponent(n1, n2, optimized)) {
         instance.next = n2
         instance.update()
       } else {
+        n2.component = n1.component
         n2.el = n1.el
       }
     }
index f7ce3941d4a0491fa4c28f5820a7fa8d87494bd4..cc12c13edf89a0ce22e7f83cf92a4dd1f6173f4c 100644 (file)
@@ -3,15 +3,13 @@ export {
   openBlock,
   createBlock,
   createVNode,
+  Text,
+  Empty,
   Fragment,
   Portal
 } from './vnode'
 
-export {
-  ComponentOptions,
-  FunctionalComponent,
-  createComponent
-} from './component'
+export { FunctionalComponent, createComponent } from './component'
 
 export { Slot, Slots } from './componentSlots'
 
index d6f9e3c287cb34d6c9a49ed20f74cef7fe3daa69..d9fc82fb9c494df6e6005cdc75f71ca0f9e03140 100644 (file)
@@ -1,4 +1,4 @@
-import { isArray, isFunction, isString, EMPTY_ARR } from '@vue/shared'
+import { isArray, isFunction, isString, isObject, EMPTY_ARR } from '@vue/shared'
 import { ComponentInstance } from './component'
 import { HostNode } from './createRenderer'
 import { RawSlots } from './componentSlots'
@@ -85,14 +85,14 @@ export function createBlock(
 
 export function createVNode(
   type: VNodeTypes,
-  props: { [key: string]: any } | null = null,
+  props: { [key: string]: any } | null | 0 = null,
   children: any = null,
   patchFlag: number | null = null,
   dynamicProps: string[] | null = null
 ): VNode {
   const vnode: VNode = {
     type,
-    props,
+    props: props || null,
     key: props && props.key,
     children: normalizeChildren(children),
     component: null,
@@ -104,7 +104,13 @@ export function createVNode(
     dynamicChildren: null
   }
   // presence of a patch flag indicates this node is dynamic
-  if (shouldTrack && patchFlag != null) {
+  // component nodes also should always be tracked, because even if the
+  // component doesn't need to update, it needs to persist the instance on to
+  // the next vnode so that it can be properly unmounted later.
+  if (
+    shouldTrack &&
+    (patchFlag != null || isObject(type) || isFunction(type))
+  ) {
     trackDynamicNode(vnode)
   }
   return vnode