]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(runtime-core): should not cache property access during data() invocation (#3299)
authorHcySunYang <HcySunYang@outlook.com>
Thu, 25 Mar 2021 19:48:12 +0000 (03:48 +0800)
committerGitHub <noreply@github.com>
Thu, 25 Mar 2021 19:48:12 +0000 (15:48 -0400)
fix #3297

packages/runtime-core/__tests__/rendererComponent.spec.ts
packages/runtime-core/src/componentOptions.ts
packages/runtime-core/src/componentPublicInstance.ts

index 4c45b90a6bd946e7110092acae6533981ee81528..02070d384e9a06a6db480f815738a491397ac979 100644 (file)
@@ -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(`<h1>1</h1>`)
+    })
+  })
 })
index 70948d41cf9ab215ce436f267267c4f7c83477e0..354c9425c4ad6fffc0de4c9235f4ce84628efefe 100644 (file)
@@ -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 ` +
index bbdb033609267c65eb98de6a916d70d4d15c1b3a..78f75d8e75745f6188e1fdb89cb64fbaa63b439d 100644 (file)
@@ -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<any> = {
       } 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
       }
     }