feat(reactivity): new effectScope API (#2195)
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
import { VNode, VNodeChild, isVNode } from './vnode'
|
||||
import {
|
||||
ReactiveEffect,
|
||||
pauseTracking,
|
||||
resetTracking,
|
||||
shallowReadonly,
|
||||
proxyRefs,
|
||||
EffectScope,
|
||||
markRaw
|
||||
} from '@vue/reactivity'
|
||||
import {
|
||||
@@ -217,11 +217,6 @@ export interface ComponentInternalInstance {
|
||||
* Root vnode of this component's own vdom tree
|
||||
*/
|
||||
subTree: VNode
|
||||
/**
|
||||
* Main update effect
|
||||
* @internal
|
||||
*/
|
||||
effect: ReactiveEffect
|
||||
/**
|
||||
* Bound effect runner to be passed to schedulers
|
||||
*/
|
||||
@@ -246,7 +241,7 @@ export interface ComponentInternalInstance {
|
||||
* so that they can be automatically stopped on component unmount
|
||||
* @internal
|
||||
*/
|
||||
effects: ReactiveEffect[] | null
|
||||
scope: EffectScope
|
||||
/**
|
||||
* cache for proxy access type to avoid hasOwnProperty calls
|
||||
* @internal
|
||||
@@ -451,14 +446,13 @@ export function createComponentInstance(
|
||||
root: null!, // to be immediately set
|
||||
next: null,
|
||||
subTree: null!, // will be set synchronously right after creation
|
||||
effect: null!, // will be set synchronously right after creation
|
||||
update: null!, // will be set synchronously right after creation
|
||||
scope: new EffectScope(),
|
||||
render: null,
|
||||
proxy: null,
|
||||
exposed: null,
|
||||
exposeProxy: null,
|
||||
withProxy: null,
|
||||
effects: null,
|
||||
provides: parent ? parent.provides : Object.create(appContext.provides),
|
||||
accessCache: null!,
|
||||
renderCache: [],
|
||||
@@ -533,10 +527,14 @@ export let currentInstance: ComponentInternalInstance | null = null
|
||||
export const getCurrentInstance: () => ComponentInternalInstance | null = () =>
|
||||
currentInstance || currentRenderingInstance
|
||||
|
||||
export const setCurrentInstance = (
|
||||
instance: ComponentInternalInstance | null
|
||||
) => {
|
||||
export const setCurrentInstance = (instance: ComponentInternalInstance) => {
|
||||
currentInstance = instance
|
||||
instance.scope.on()
|
||||
}
|
||||
|
||||
export const unsetCurrentInstance = () => {
|
||||
currentInstance && currentInstance.scope.off()
|
||||
currentInstance = null
|
||||
}
|
||||
|
||||
const isBuiltInTag = /*#__PURE__*/ makeMap('slot,component')
|
||||
@@ -618,7 +616,7 @@ function setupStatefulComponent(
|
||||
const setupContext = (instance.setupContext =
|
||||
setup.length > 1 ? createSetupContext(instance) : null)
|
||||
|
||||
currentInstance = instance
|
||||
setCurrentInstance(instance)
|
||||
pauseTracking()
|
||||
const setupResult = callWithErrorHandling(
|
||||
setup,
|
||||
@@ -627,13 +625,10 @@ function setupStatefulComponent(
|
||||
[__DEV__ ? shallowReadonly(instance.props) : instance.props, setupContext]
|
||||
)
|
||||
resetTracking()
|
||||
currentInstance = null
|
||||
unsetCurrentInstance()
|
||||
|
||||
if (isPromise(setupResult)) {
|
||||
const unsetInstance = () => {
|
||||
currentInstance = null
|
||||
}
|
||||
setupResult.then(unsetInstance, unsetInstance)
|
||||
setupResult.then(unsetCurrentInstance, unsetCurrentInstance)
|
||||
|
||||
if (isSSR) {
|
||||
// return the promise so server-renderer can wait on it
|
||||
@@ -801,11 +796,11 @@ export function finishComponentSetup(
|
||||
|
||||
// support for 2.x options
|
||||
if (__FEATURE_OPTIONS_API__ && !(__COMPAT__ && skipOptions)) {
|
||||
currentInstance = instance
|
||||
setCurrentInstance(instance)
|
||||
pauseTracking()
|
||||
applyOptions(instance)
|
||||
resetTracking()
|
||||
currentInstance = null
|
||||
unsetCurrentInstance()
|
||||
}
|
||||
|
||||
// warn missing template/render
|
||||
@@ -900,17 +895,6 @@ export function getExposeProxy(instance: ComponentInternalInstance) {
|
||||
}
|
||||
}
|
||||
|
||||
// record effects created during a component's setup() so that they can be
|
||||
// stopped when the component unmounts
|
||||
export function recordInstanceBoundEffect(
|
||||
effect: ReactiveEffect,
|
||||
instance = currentInstance
|
||||
) {
|
||||
if (instance) {
|
||||
;(instance.effects || (instance.effects = [])).push(effect)
|
||||
}
|
||||
}
|
||||
|
||||
const classifyRE = /(?:^|[-_])(\w)/g
|
||||
const classify = (str: string): string =>
|
||||
str.replace(classifyRE, c => c.toUpperCase()).replace(/[-_]/g, '')
|
||||
|
||||
Reference in New Issue
Block a user