• vue computed


    new Vue后:
    Vue.prototype._init= function(...){
      initLifecycle(vm) //初始化生命周期

      initEvents(vm) //初始化事件中心

      initRender(vm) //初始化渲染

      initState(vm) //初始化状态
    }

    function initState(){

      vm._watchers= [] //所有watcher

      const opts= vm.$options

      initProps()

      initMethods()

      initData()//先初始化data中的属性

      initComputed(vm, opts.computed) //初始化computed属性

      initWatch()

    }

    const computedWatcherOptions= {computed: true}

    function initComputed(vm, computed){

      const watchers= vm._computedWatchers= Object.create(null) //所有computed属性

      for(const key in computed){

        const userDef= computed[key] //computed属性定义,函数形式或者对象形式(getter与setter)

        const getter= typeof userDef === 'function'? userDef: userDef.get //提取getter

        //创建computed属性的watcher,每个computed属性都有一个watcher

        watchers[key]= new Watcher(

          vm,

          getter,

          noop,

          computedWatcherOptions //computed watcher特有属性

        )

        //防止属性名被占用

        if(!(key in vm)){

          defineComputed(vm, key, userDef) //定义computed属性

        }

      }

    }

    //绑定体

    const sharedPropertyDefinition= {

      enumerable: true, configurable: true,

      get: noop, set: noop

    }

    //绑定属性,定义getter、setter

    function defineComputed(vm, key, userDef){

      //函数形式

      if(typeof userDef === 'function'){

        sharedPropertyDefinition.get= createComputedGetter(key)

        sharedPropertyDefinition.set= noop

      }

      //对象形式

      else {

        sharedPropertyDefinition.get= createComputedGetter(key)

      }

      //绑定

      Object.defineProperty(target, key, sharedPropertyDefinition)

    }

    //创建getter

    function createComputedGetter(){

      //注意这里返回一个函数,此函数执行时机为计算属性被调用时

      return function computedGetter(){

        const watcher = this._computedWatchers[key] //该属性的watcher

        if(watcher){

          watcher.depend() //收集所依赖的

          return watcher.evaluate()

        }

      }

    }

    //当计算属性被调用(执行get方法),执行computedGetter函数

    //访问属性->挟持对象的get方法->

    //这里穿插一下watcher的构造函数

    class Watcher{

      constructor(

        vm,

        expOrFn, //定义用的getter函数

        cb, //这里为noop

        options //{computed: true}

      )

      vm._watchers.push(this) //加入全局watcher数组

      if(options){

        this.computed= !!options.computed //true

        ....

      }

      this.id= ++uid

      this.dirty= this.computed //脏值检测

      this.deps= [] //订阅器(一个watcher可以有多个订阅器)

      this.getter= expOrFn //getter真多

      if(this.computed){

        this.value= undefined //计算属性的值
        this.dep= new Dep() //创建消息订阅器

      }

    }

    //处理自己所依赖的属性

    Watcher.prototype.addDep = function addDep (dep) {
      var id = dep.id;
      if (!this.newDepIds.has(id)) {
        this.newDepIds.add(id);
        this.newDeps.push(dep);
        if (!this.depIds.has(id)) {
          dep.addSub(this);
        }
      }
    };
     

    class Dep {

      constructo(){

        this.uid= uid++

        this.subs= []

      }

      addSub(sub: Watcher){

        this.subs.push(sub)

      }

      removeSub(sub: Watcher){

      }

      //将自己加到watcher的订阅器数组中

      depend(){

        if(Dep.target){

          Dep.target.addDep(this)

        }

      }

      //通知订阅器里的每一个订阅者(watcher)去更新

      notify(){

        const subs= this.subs.slice()

        for(var i=0;i<subs.length;i++){

          subs[i].update()

        }

      }

    }

    回到computedwatcher的getter中:

    if(watcher){

      watcher.depend() //收集所依赖自己的属性

      return watcher.evaluate() //处理所依赖的属性

    }

    watcher.depend= function(){

      //注意Dep.target为当前watcher

      if(this.dep && Dep.target){

        this.dep.depend() //结合Dep的定义 本质上是调用了watcher.addDep() 添加订阅器

      }

    }

    -----------------------------------------------------------------------------------------------------------------

    watcher.evaluate= function(){

      //当所依赖的值发生改变的时候dirty为true,这就是依赖缓存!

      if(this.dirty){

        this.value= this.get()

        this.dirty= false

      }

      return this.value

    }

    备注:

    get()

    this.getter.call() 

    调用定义的getter

    computedWatcher.depend() 咋一看是处理所依赖的属性,其实恰恰相反,这里是处理依赖于自己的watcher

    ->computedWatcher.dep.depend()

    ->Dep.target.addDep(this/computedWatcher.dep) //这里发生在getter中,Dep.target为依赖于自己的watcherwatcher,this为computedwatcher

    ->watcher.addDep(this/computedWatcher.dep)

    语义很重要!!总之核心就是computedWatcher.depend()调用Dep.target.addDep(computedWatcher.dep),computedWatcher将Dep.target(即watcher)添加到自己的subs中

  • 相关阅读:
    postman 的基础使用篇(一)
    C# struct
    细说javascript typeof操作符
    javascript-void keyword
    深圳求生记
    博客园开篇--对程序员的一点看法
    京东2018校园招聘 数据开发
    数据结构之哈希、哈希函数、哈希表
    scrapy入门教程
    linux学习笔记1
  • 原文地址:https://www.cnblogs.com/yanze/p/11775493.html
Copyright © 2020-2023  润新知