vue3的computed和ref是什么关系

ref无论在结构还是使用上都和computed几乎一致,ref主要是为了给原始类型(premitive type)设置响应式,而computed计算属性,为的是代替在模板中直接使用函数,并且提供了缓存机制,以及提供了响应式。实际上这两个函数都有两个共同的属性—-valuedep

value没什么要说的,就是,这里重点提一下dep,实际上dep存储的是ref或者computed当前的ReactiveEffect

vue3的computed和ref是什么关系

当然首先要了解什么是ReactiveEffect,实际上这是副作用的一层包装,我们可以通过几个重要的属性来了解它:

  1. fn:执行这个函数时,会执行track,把ReactiveEffect添加到dep
  2. scheduler:这个是副作用函数,上图中就是componentUpdateFn,实际上被模板引用都会有这个函数,就是更新dom
  3. onTrack:调试用的钩子,在追踪依赖时触发,实际上在computed第二个参数有相同名称的选项,computed传递了onTrack参数之后,这里会出现相同的引用:

vue3的computed和ref是什么关系

  1. onTrigger:调试用钩子,依赖触发时调用,其它和onTrack一样
  2. run:实际上vue维护了一个ReactiveEffect栈,来处理嵌套副作用,所以这个函数实际上是用来处理副作用,并调用fn,然后返回fn返回值

当然还有一个知识点要了解,就是trigger,track,这两个是响应式系统的核心,track追踪函数,创建对应的ReactiveEffect,在操作的时候执行。trigger是触发函数,执行对应的ReactiveEffect函数,在的时候执行。

然后抛出几个问题,来理解refcomputed的关系

  1. 为什么computed中书写的ref值改变时,会触发computed对应的副作用
<script setup>
import { ref, watch,computed } from 'vue';

const a = ref(1)
const b = computed(() => a.value)

watch(b,()=>{
  console.log(b.value)
})

a.value++
</script>

vue3的computed和ref是什么关系

实际上,computed的源码中,让ref的值,主动添加了对当前effect的引用:

vue3的computed和ref是什么关系

所以,ref改变时,就触发了triggerRefValue来执行computeddeps

2.当computed只有getter时,为什么computed(()=> Data.now())永远不会变?

实际上computed上还有一个非常重要的属性_dirty,这个属性是用来判断当前值是否发生变化的,是做缓存用的。如果是false的话,则永远不会重新执行run,也就不会拿到新值

vue3的computed和ref是什么关系

但是ref值变化时会更新_dirty:

vue3的computed和ref是什么关系

所以ref值会刷新computed_dirty属性,并执行computted副作用

原文链接:https://juejin.cn/post/7258337246024187959 作者:RadiumAg

(0)
上一篇 2023年7月23日 上午10:39
下一篇 2023年7月23日 上午10:50

相关推荐

发表回复

登录后才能评论