美文网首页
Vue3源码--响应式原理3(应用)

Vue3源码--响应式原理3(应用)

作者: 勤奋的大鱼 | 来源:发表于2020-03-08 23:50 被阅读0次

     前两篇写了响应式系统的两个核心模块effect,reactivity,这篇写一下响应式系统在源码中的应用吧。

    Computed API

     话不多说,首先来看一下利用响应式系统实现computed api,直接上代码注释。

    // 3.x的computed 支持设置setter,setter的逻辑很简单,就不多说了,这里删掉了相关的代码。
    // 大部分的情况下传入的是一个function, 也就是getter
    export function computed<T>(
      getterOrOptions: ComputedGetter<T> | WritableComputedOptions<T>
    ) {
      let getter: ComputedGetter<T>
    
      let dirty = true
      let value: T
      let computed: ComputedRef<T>
      // 每个computed中都会维护一个lazy effect实例
      const runner = effect(getter, {
        lazy: true,
        // mark effect as computed so that it gets priority during trigger
        computed: true,
        // 注意:这个scheduler并不执行effect,仅仅把dirty设置为true
        scheduler: () => {
          if (!dirty) {
            dirty = true
            // 触发依赖这个computed的effects
            trigger(computed, TriggerOpTypes.SET, 'value')
          }
        }
      })
      computed = {
        _isRef: true,
        // expose effect so computed can be stopped
        effect: runner,
        get value() {
          // 如果数据是脏的,就执行自身的effect获取最新数据,否则直接返回缓存的数据
          if (dirty) {
            value = runner()
            dirty = false
          }
          // 此时如果有active effect的话,就会被收集到computed的depsMap里面
          track(computed, TrackOpTypes.GET, 'value')
          return value
        }
      } as any
      return computed
    }
    
    

    我试着用语言描述一下:

    1. computed和ref一样,返回一个封装的对象,实际上他的_isRef就是true
    2. 内部维护一个lazy effect,之前也讲过,lazy effect不会立刻执行
    3. 在第一次获取这个computed的值的时候,执行这个lazy effect,此时active effect就是这个lazy effect,computed里面的响应式数据都会收集到这个lazy effect,
    4. 当computed的响应式数据发生改变,由于设置了scheduler,并不会去执行这个lazy effect,而是把这个computed标示为脏,然后直接trigger这个computed下所有的effect。(如果computed是在render中调用的话,那么就相当于重新去执行render的过程)

    Watch API

      去看watch api的源码packages/runtime-core/src/apiWatch.ts, 会发现好长,其实watch api的原理最简单了,effect方法的作用是监听传入的函数,如果响应式数据发生改变,那么就重新执行这个函数,而effect方法支持scheduler配置,如果传入了scheduler方法,就不会直接重新执行这个effect,我们只需要在shceduler方法里面去执行watch api的回调即可。

     终于写完响应式原理相关的了,发现写这种源码解读的文章是真难,不过这个过程需要组织语言去描述,自己还是加深了理解。后面接下去本来打算写compile相关的内容,但是感觉如果像响应式这样写的话也太难面面俱到了,也没有那么多精力。因此打算最后写几篇,内容就是vue3.x相比2.x快在哪里,做了哪些优化。

    相关文章

      网友评论

          本文标题:Vue3源码--响应式原理3(应用)

          本文链接:https://www.haomeiwen.com/subject/ffesdhtx.html