]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
wip: component update fast path
authorEvan You <yyx990803@gmail.com>
Thu, 30 May 2019 08:00:42 +0000 (16:00 +0800)
committerEvan You <yyx990803@gmail.com>
Thu, 30 May 2019 08:00:42 +0000 (16:00 +0800)
packages/runtime-core/src/component.ts
packages/runtime-core/src/patchFlags.ts
packages/runtime-core/src/vnode.ts

index 8b7cea0bce4d6bc31afb10099e532ccef9344ea5..6f61660edf72011178e47e4a0bcc11fe42458779 100644 (file)
@@ -3,6 +3,7 @@ import { ReactiveEffect, UnwrapValue, observable } from '@vue/observer'
 import { isFunction, EMPTY_OBJ } from '@vue/shared'
 import { RenderProxyHandlers } from './componentProxy'
 import { ComponentPropsOptions, PropValidator } from './componentProps'
+import { PROPS, SLOTS } from './patchFlags'
 
 export type Data = { [key: string]: any }
 
@@ -167,36 +168,43 @@ export function shouldUpdateComponent(
   nextVNode: VNode
 ): boolean {
   const { props: prevProps } = prevVNode
-  const { props: nextProps } = nextVNode
-
-  // TODO handle slots
-  // If has different slots content, or has non-compiled slots,
-  // the child needs to be force updated.
-  // if (
-  //   prevChildFlags !== nextChildFlags ||
-  //   (nextChildFlags & ChildrenFlags.DYNAMIC_SLOTS) > 0
-  // ) {
-  //   return true
-  // }
-
-  if (prevProps === nextProps) {
-    return false
-  }
-  if (prevProps === null) {
-    return nextProps !== null
-  }
-  if (nextProps === null) {
-    return prevProps !== null
-  }
-  const nextKeys = Object.keys(nextProps)
-  if (nextKeys.length !== Object.keys(prevProps).length) {
-    return true
-  }
-  for (let i = 0; i < nextKeys.length; i++) {
-    const key = nextKeys[i]
-    if (nextProps[key] !== prevProps[key]) {
+  const { props: nextProps, patchFlag } = nextVNode
+  if (patchFlag !== null) {
+    if (patchFlag & SLOTS) {
+      // slot content that references values that might have changed,
+      // e.g. in a v-for
+      return true
+    }
+    if (patchFlag & PROPS) {
+      const dynamicProps = nextVNode.dynamicProps as string[]
+      for (let i = 0; i < dynamicProps.length; i++) {
+        const key = dynamicProps[i]
+        if ((nextProps as any)[key] !== (prevProps as any)[key]) {
+          return true
+        }
+      }
+    }
+  } else {
+    // TODO handle slots
+    if (prevProps === nextProps) {
+      return false
+    }
+    if (prevProps === null) {
+      return nextProps !== null
+    }
+    if (nextProps === null) {
+      return prevProps !== null
+    }
+    const nextKeys = Object.keys(nextProps)
+    if (nextKeys.length !== Object.keys(prevProps).length) {
       return true
     }
+    for (let i = 0; i < nextKeys.length; i++) {
+      const key = nextKeys[i]
+      if (nextProps[key] !== prevProps[key]) {
+        return true
+      }
+    }
   }
   return false
 }
index 5d6a0b7f3488957b937642daf03ccc0432db0be7..f28ffd15366abe945659cd6483af3bda60510d98 100644 (file)
@@ -4,3 +4,4 @@ export const STYLE = 1 << 2
 export const PROPS = 1 << 3
 export const KEYED = 1 << 4
 export const UNKEYED = 1 << 5
+export const SLOTS = 1 << 6 // component only
index 2b06f224801522cb59d4db084910a3881f25f261..8dca305ac13d05356383b306dff7a81dfa297379 100644 (file)
@@ -1,4 +1,4 @@
-import { isArray, isFunction, EMPTY_ARR } from '@vue/shared'
+import { isArray, EMPTY_ARR } from '@vue/shared'
 import { ComponentInstance } from './component'
 import { HostNode } from './createRenderer'
 
@@ -87,7 +87,7 @@ export function createVNode(
     dynamicProps,
     dynamicChildren: null
   }
-  if (shouldTrack && (patchFlag != null || isFunction(type))) {
+  if (shouldTrack && patchFlag != null) {
     trackDynamicNode(vnode)
   }
   return vnode