diff --git a/packages/runtime-core/__tests__/rendererComponent.spec.ts b/packages/runtime-core/__tests__/rendererComponent.spec.ts
index 4c45b90a6bd..02070d384e9 100644
--- a/packages/runtime-core/__tests__/rendererComponent.spec.ts
+++ b/packages/runtime-core/__tests__/rendererComponent.spec.ts
@@ -275,4 +275,25 @@ describe('renderer: component', () => {
await nextTick()
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(`
1
`)
+ })
+ })
})
diff --git a/packages/runtime-core/src/componentOptions.ts b/packages/runtime-core/src/componentOptions.ts
index 70948d41cf9..354c9425c4a 100644
--- a/packages/runtime-core/src/componentOptions.ts
+++ b/packages/runtime-core/src/componentOptions.ts
@@ -465,7 +465,7 @@ function createDuplicateChecker() {
type DataFn = (vm: ComponentPublicInstance) => any
-export let isInBeforeCreate = false
+export let shouldCacheAccess = true
export function applyOptions(
instance: ComponentInternalInstance,
@@ -518,7 +518,7 @@ export function applyOptions(
// applyOptions is called non-as-mixin once per instance
if (!asMixin) {
- isInBeforeCreate = true
+ shouldCacheAccess = false
callSyncHook(
'beforeCreate',
LifecycleHooks.BEFORE_CREATE,
@@ -526,7 +526,7 @@ export function applyOptions(
instance,
globalMixins
)
- isInBeforeCreate = false
+ shouldCacheAccess = true
// global mixins are applied first
applyMixins(
instance,
@@ -893,7 +893,9 @@ function resolveData(
`Plain object usage is no longer supported.`
)
}
+ shouldCacheAccess = false
const data = dataFn.call(publicThis, publicThis)
+ shouldCacheAccess = true
if (__DEV__ && isPromise(data)) {
warn(
`data() returned a Promise - note data() cannot be async; If you ` +
diff --git a/packages/runtime-core/src/componentPublicInstance.ts b/packages/runtime-core/src/componentPublicInstance.ts
index bbdb0336092..78f75d8e757 100644
--- a/packages/runtime-core/src/componentPublicInstance.ts
+++ b/packages/runtime-core/src/componentPublicInstance.ts
@@ -31,7 +31,7 @@ import {
OptionTypesType,
OptionTypesKeys,
resolveMergedOptions,
- isInBeforeCreate
+ shouldCacheAccess
} from './componentOptions'
import { EmitsOptions, EmitFn } from './componentEmits'
import { Slots } from './componentSlots'
@@ -305,7 +305,7 @@ export const PublicInstanceProxyHandlers: ProxyHandler = {
} else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {
accessCache![key] = AccessTypes.CONTEXT
return ctx[key]
- } else if (!__FEATURE_OPTIONS_API__ || !isInBeforeCreate) {
+ } else if (!__FEATURE_OPTIONS_API__ || shouldCacheAccess) {
accessCache![key] = AccessTypes.OTHER
}
}