Prechádzať zdrojové kódy

fix: fix effect scope tracking for manually created instances

fix #12705
Evan You 3 rokov pred
rodič
commit
7161176cd0

+ 1 - 0
src/core/instance/init.ts

@@ -34,6 +34,7 @@ export function initMixin(Vue: typeof Component) {
     vm.__v_skip = true
     // effect scope
     vm._scope = new EffectScope(true /* detached */)
+    vm._scope._vm = true
     // merge options
     if (options && options._isComponent) {
       // optimize internal component instantiation

+ 0 - 2
src/core/instance/lifecycle.ts

@@ -209,7 +209,6 @@ export function mountComponent(
   // we set this to vm._watcher inside the watcher's constructor
   // since the watcher's initial patch may call $forceUpdate (e.g. inside child
   // component's mounted hook), which relies on vm._watcher being already defined
-  vm._scope.on()
   new Watcher(
     vm,
     updateComponent,
@@ -217,7 +216,6 @@ export function mountComponent(
     watcherOptions,
     true /* isRenderWatcher */
   )
-  vm._scope.off()
   hydrating = false
 
   // flush buffer for flush: "pre" watchers queued in setup()

+ 10 - 1
src/core/observer/watcher.ts

@@ -71,7 +71,16 @@ export default class Watcher implements DepTarget {
     options?: WatcherOptions | null,
     isRenderWatcher?: boolean
   ) {
-    recordEffectScope(this, activeEffectScope || (vm ? vm._scope : undefined))
+    recordEffectScope(
+      this,
+      // if the active effect scope is manually created (not a component scope),
+      // prioritize it
+      activeEffectScope && !activeEffectScope._vm
+        ? activeEffectScope
+        : vm
+        ? vm._scope
+        : undefined
+    )
     if ((this.vm = vm) && isRenderWatcher) {
       vm._watcher = this
     }

+ 5 - 1
src/v3/reactivity/effectScope.ts

@@ -27,10 +27,14 @@ export class EffectScope {
    * @internal
    */
   scopes: EffectScope[] | undefined
+  /**
+   * indicates this being a component root scope
+   * @internal
+   */
+  _vm?: boolean
   /**
    * track a child scope's index in its parent's scopes array for optimized
    * removal
-   * @internal
    */
   private index: number | undefined