Skip to content

Commit 6e88156

Browse files
authored
fix(runtime-core): should not cache property access during data() invocation (#3299)
fix #3297
1 parent 4bf7ba1 commit 6e88156

File tree

3 files changed

+28
-5
lines changed

3 files changed

+28
-5
lines changed

packages/runtime-core/__tests__/rendererComponent.spec.ts

+21
Original file line numberDiff line numberDiff line change
@@ -275,4 +275,25 @@ describe('renderer: component', () => {
275275
await nextTick()
276276
expect(App.updated).toHaveBeenCalledTimes(0)
277277
})
278+
279+
describe('render with access caches', () => {
280+
// #3297
281+
test('should not set the access cache in the data() function (production mode)', () => {
282+
const Comp = {
283+
data() {
284+
;(this as any).foo
285+
return { foo: 1 }
286+
},
287+
render() {
288+
return h('h1', (this as any).foo)
289+
}
290+
}
291+
const root = nodeOps.createElement('div')
292+
293+
__DEV__ = false
294+
render(h(Comp), root)
295+
__DEV__ = true
296+
expect(serializeInner(root)).toBe(`<h1>1</h1>`)
297+
})
298+
})
278299
})

packages/runtime-core/src/componentOptions.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ function createDuplicateChecker() {
465465

466466
type DataFn = (vm: ComponentPublicInstance) => any
467467

468-
export let isInBeforeCreate = false
468+
export let shouldCacheAccess = true
469469

470470
export function applyOptions(
471471
instance: ComponentInternalInstance,
@@ -518,15 +518,15 @@ export function applyOptions(
518518

519519
// applyOptions is called non-as-mixin once per instance
520520
if (!asMixin) {
521-
isInBeforeCreate = true
521+
shouldCacheAccess = false
522522
callSyncHook(
523523
'beforeCreate',
524524
LifecycleHooks.BEFORE_CREATE,
525525
options,
526526
instance,
527527
globalMixins
528528
)
529-
isInBeforeCreate = false
529+
shouldCacheAccess = true
530530
// global mixins are applied first
531531
applyMixins(
532532
instance,
@@ -893,7 +893,9 @@ function resolveData(
893893
`Plain object usage is no longer supported.`
894894
)
895895
}
896+
shouldCacheAccess = false
896897
const data = dataFn.call(publicThis, publicThis)
898+
shouldCacheAccess = true
897899
if (__DEV__ && isPromise(data)) {
898900
warn(
899901
`data() returned a Promise - note data() cannot be async; If you ` +

packages/runtime-core/src/componentPublicInstance.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import {
3131
OptionTypesType,
3232
OptionTypesKeys,
3333
resolveMergedOptions,
34-
isInBeforeCreate
34+
shouldCacheAccess
3535
} from './componentOptions'
3636
import { EmitsOptions, EmitFn } from './componentEmits'
3737
import { Slots } from './componentSlots'
@@ -305,7 +305,7 @@ export const PublicInstanceProxyHandlers: ProxyHandler<any> = {
305305
} else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {
306306
accessCache![key] = AccessTypes.CONTEXT
307307
return ctx[key]
308-
} else if (!__FEATURE_OPTIONS_API__ || !isInBeforeCreate) {
308+
} else if (!__FEATURE_OPTIONS_API__ || shouldCacheAccess) {
309309
accessCache![key] = AccessTypes.OTHER
310310
}
311311
}

0 commit comments

Comments
 (0)