fix(runtime-core): cache props default values to avoid unnecessary watcher trigger (#3474)

fix #3471
This commit is contained in:
HcySunYang
2021-03-26 05:26:58 +08:00
committed by GitHub
parent ebedcccdc0
commit 44166b43d9
3 changed files with 61 additions and 5 deletions

View File

@@ -302,7 +302,12 @@ export interface ComponentInternalInstance {
* @internal
*/
emitted: Record<string, boolean> | null
/**
* used for caching the value returned from props default factory functions to
* avoid unnecessary watcher trigger
* @internal
*/
propsDefaults: Data
/**
* setup related
* @internal
@@ -440,6 +445,9 @@ export function createComponentInstance(
emit: null as any, // to be set immediately
emitted: null,
// props default value
propsDefaults: EMPTY_OBJ,
// state
ctx: EMPTY_OBJ,
data: EMPTY_OBJ,

View File

@@ -139,6 +139,9 @@ export function initProps(
const props: Data = {}
const attrs: Data = {}
def(attrs, InternalObjectKey, 1)
instance.propsDefaults = Object.create(null)
setFullProps(instance, rawProps, props, attrs)
// validation
if (__DEV__) {
@@ -326,9 +329,14 @@ function resolvePropValue(
if (hasDefault && value === undefined) {
const defaultValue = opt.default
if (opt.type !== Function && isFunction(defaultValue)) {
setCurrentInstance(instance)
value = defaultValue(props)
setCurrentInstance(null)
const { propsDefaults } = instance
if (key in propsDefaults) {
value = propsDefaults[key]
} else {
setCurrentInstance(instance)
value = propsDefaults[key] = defaultValue(props)
setCurrentInstance(null)
}
} else {
value = defaultValue
}