wip: component update fast path

This commit is contained in:
Evan You 2019-05-30 16:00:42 +08:00
parent b82b7af29b
commit 200c035862
3 changed files with 39 additions and 30 deletions

View File

@ -3,6 +3,7 @@ import { ReactiveEffect, UnwrapValue, observable } from '@vue/observer'
import { isFunction, EMPTY_OBJ } from '@vue/shared' import { isFunction, EMPTY_OBJ } from '@vue/shared'
import { RenderProxyHandlers } from './componentProxy' import { RenderProxyHandlers } from './componentProxy'
import { ComponentPropsOptions, PropValidator } from './componentProps' import { ComponentPropsOptions, PropValidator } from './componentProps'
import { PROPS, SLOTS } from './patchFlags'
export type Data = { [key: string]: any } export type Data = { [key: string]: any }
@ -167,18 +168,24 @@ export function shouldUpdateComponent(
nextVNode: VNode nextVNode: VNode
): boolean { ): boolean {
const { props: prevProps } = prevVNode const { props: prevProps } = prevVNode
const { props: nextProps } = nextVNode 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 // 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) { if (prevProps === nextProps) {
return false return false
} }
@ -198,5 +205,6 @@ export function shouldUpdateComponent(
return true return true
} }
} }
}
return false return false
} }

View File

@ -4,3 +4,4 @@ export const STYLE = 1 << 2
export const PROPS = 1 << 3 export const PROPS = 1 << 3
export const KEYED = 1 << 4 export const KEYED = 1 << 4
export const UNKEYED = 1 << 5 export const UNKEYED = 1 << 5
export const SLOTS = 1 << 6 // component only

View 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 { ComponentInstance } from './component'
import { HostNode } from './createRenderer' import { HostNode } from './createRenderer'
@ -87,7 +87,7 @@ export function createVNode(
dynamicProps, dynamicProps,
dynamicChildren: null dynamicChildren: null
} }
if (shouldTrack && (patchFlag != null || isFunction(type))) { if (shouldTrack && patchFlag != null) {
trackDynamicNode(vnode) trackDynamicNode(vnode)
} }
return vnode return vnode