fix(runtime-core): should not cache property access during data() invocation (#3299)
fix #3297
This commit is contained in:
parent
4bf7ba19bf
commit
6e88156934
@ -275,4 +275,25 @@ describe('renderer: component', () => {
|
|||||||
await nextTick()
|
await nextTick()
|
||||||
expect(App.updated).toHaveBeenCalledTimes(0)
|
expect(App.updated).toHaveBeenCalledTimes(0)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('render with access caches', () => {
|
||||||
|
// #3297
|
||||||
|
test('should not set the access cache in the data() function (production mode)', () => {
|
||||||
|
const Comp = {
|
||||||
|
data() {
|
||||||
|
;(this as any).foo
|
||||||
|
return { foo: 1 }
|
||||||
|
},
|
||||||
|
render() {
|
||||||
|
return h('h1', (this as any).foo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const root = nodeOps.createElement('div')
|
||||||
|
|
||||||
|
__DEV__ = false
|
||||||
|
render(h(Comp), root)
|
||||||
|
__DEV__ = true
|
||||||
|
expect(serializeInner(root)).toBe(`<h1>1</h1>`)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -465,7 +465,7 @@ function createDuplicateChecker() {
|
|||||||
|
|
||||||
type DataFn = (vm: ComponentPublicInstance) => any
|
type DataFn = (vm: ComponentPublicInstance) => any
|
||||||
|
|
||||||
export let isInBeforeCreate = false
|
export let shouldCacheAccess = true
|
||||||
|
|
||||||
export function applyOptions(
|
export function applyOptions(
|
||||||
instance: ComponentInternalInstance,
|
instance: ComponentInternalInstance,
|
||||||
@ -518,7 +518,7 @@ export function applyOptions(
|
|||||||
|
|
||||||
// applyOptions is called non-as-mixin once per instance
|
// applyOptions is called non-as-mixin once per instance
|
||||||
if (!asMixin) {
|
if (!asMixin) {
|
||||||
isInBeforeCreate = true
|
shouldCacheAccess = false
|
||||||
callSyncHook(
|
callSyncHook(
|
||||||
'beforeCreate',
|
'beforeCreate',
|
||||||
LifecycleHooks.BEFORE_CREATE,
|
LifecycleHooks.BEFORE_CREATE,
|
||||||
@ -526,7 +526,7 @@ export function applyOptions(
|
|||||||
instance,
|
instance,
|
||||||
globalMixins
|
globalMixins
|
||||||
)
|
)
|
||||||
isInBeforeCreate = false
|
shouldCacheAccess = true
|
||||||
// global mixins are applied first
|
// global mixins are applied first
|
||||||
applyMixins(
|
applyMixins(
|
||||||
instance,
|
instance,
|
||||||
@ -893,7 +893,9 @@ function resolveData(
|
|||||||
`Plain object usage is no longer supported.`
|
`Plain object usage is no longer supported.`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
shouldCacheAccess = false
|
||||||
const data = dataFn.call(publicThis, publicThis)
|
const data = dataFn.call(publicThis, publicThis)
|
||||||
|
shouldCacheAccess = true
|
||||||
if (__DEV__ && isPromise(data)) {
|
if (__DEV__ && isPromise(data)) {
|
||||||
warn(
|
warn(
|
||||||
`data() returned a Promise - note data() cannot be async; If you ` +
|
`data() returned a Promise - note data() cannot be async; If you ` +
|
||||||
|
@ -31,7 +31,7 @@ import {
|
|||||||
OptionTypesType,
|
OptionTypesType,
|
||||||
OptionTypesKeys,
|
OptionTypesKeys,
|
||||||
resolveMergedOptions,
|
resolveMergedOptions,
|
||||||
isInBeforeCreate
|
shouldCacheAccess
|
||||||
} from './componentOptions'
|
} from './componentOptions'
|
||||||
import { EmitsOptions, EmitFn } from './componentEmits'
|
import { EmitsOptions, EmitFn } from './componentEmits'
|
||||||
import { Slots } from './componentSlots'
|
import { Slots } from './componentSlots'
|
||||||
@ -305,7 +305,7 @@ export const PublicInstanceProxyHandlers: ProxyHandler<any> = {
|
|||||||
} else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {
|
} else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {
|
||||||
accessCache![key] = AccessTypes.CONTEXT
|
accessCache![key] = AccessTypes.CONTEXT
|
||||||
return ctx[key]
|
return ctx[key]
|
||||||
} else if (!__FEATURE_OPTIONS_API__ || !isInBeforeCreate) {
|
} else if (!__FEATURE_OPTIONS_API__ || shouldCacheAccess) {
|
||||||
accessCache![key] = AccessTypes.OTHER
|
accessCache![key] = AccessTypes.OTHER
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user