vue3中的effectScope解决响应式带来的副作用
前言(什么是effectScope)
effectScope
是vue3
引入的一个功能,它是响应式系统的一部分,可以用来在vue
的composition API
中管理副作用(effects),通过effectScope
,我们可以更好地控制和管理副作用,特别是在构建大型的应用的使用,这能够提高代码的组织性和可维护性!
😕 那么什么是副作用?
👉 在vue
中,副作用(effects
)主要是指响应式依赖的注册过程,比如,当使用computed
或者watch
等“监听性质”的API时,vue
内部会建立起一个响应式系统,自动跟踪相关依赖,并在依赖变化时重新执行这些副作用,以保证数据与视图的同步!
这里我将effectScope
称之为一种“自动的可管理的垃圾(依赖)处理容器”
为什么要使用effectScope
在没有
effectScope
之前,vue
实例本身应该会跟踪这些副作用,然后在组件销毁(unmounted)的时候,自动销毁这些副作用的,但是随着composition API
的使用越来越广泛,应用的结构也变得越来越灵活,原有的副作用跟踪机制在某些场景下显得不够灵活和直观,或者用起来不够顺畅,因此,使用effectScope
来解决这个问题,它允许开发者显示地组织和管理副作用!
如何使用effectScope
1 | import { ref, effectScope } from 'vue' |
⭐ 这里我们通过effectScope()
来创建一个scope容器对象,然后通过其run()
方法将所有的副作用在run()
方法的参数中来实现!这里我们针对count变量创建了一个watch副作用,然后在需要销毁副作用的时候通过调用这个scope.stop()
方法来销毁容器内的所有副作用!
从上面我们可以看出关于通过effectScope()
方法所创建出来的EffectScope
实例对象拥有run
与stop
方法,其数据结构如下
1 | interface EffectScope { |
🌟 关于这个effectScope(detached: boolean)
这个API中,还提供了一个boolean参数detached
,该参数为true
时代表一个被嵌套的scope
不可以被其父scope
收集,当父scope
被销毁的时候,这个scope
将不会被连带stop,只有显示地调用这个scope
的stop()
才被正常销毁!
🌟 而且在vue3
中除了effectScope()
API之外,还提供了另外两个API:
- getCurrentScope(): 获取当前
scope
; - onScopeDispose(fn: () => void): void: 当当前的scope被销毁的时候,自动执行的回调方法!
🌟 在组件component
内部通过onUnmounted()
来销毁资源的,那么对于在非组件层面(比如composable function)中,所创建出来的响应式副作用则可以通过onScopeDispose()
来进行管理销毁回调操作,如下所示:
1 | import { onScopeDispose } from 'vue' |
可使用effectScope的场景
vue3
的setup
本身就提供了自动副作用管理的机制,一般在setup
中创建的响应式引用(ref
或者reactive
)以及副作用(如watch
、computed
)等注册的,都会被vue
自动跟踪和管理,当组件卸载时,这些副作用也会被自动清理,无需开发者接入!
🫣 这一点,vue
已经帮开发者做得足够好了, 😕 那么关于effectScope
的使用场景是什么呢?主要有 👇 场景
组合式函数的重用逻辑
在某些复杂的场景下,可能需要更加精细化地来控制副作用的激活与停止,而不仅仅是绑定到组件的生命周期上!
比如 🈶 这么的一个功能,当用户完成某些操作之后,需要启动一个副作用来进行数据的实时更新,但这个功能可能需要根据用户的操作来多次开启与关闭
1 | // realTimeUpdates.js |
🥸 effectScope
为我们提供了一种方便的方式来精细化地管理副作用,无论是在组件内部还是在全局环境或者可重用逻辑中,借助于effectScope
,可以更好地控制程序行为,确保资源被适时地释放,从而提供应用的性能和可维护性!