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,可以更好地控制程序行为,确保资源被适时地释放,从而提供应用的性能和可维护性!
