最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 梳理一下你脑子中vue的watch源码!!!

    正文概述 掘金(诺颜)   2021-04-05   597

    前言


    首先让我们看看初始化的watch的源码!

    function Vue(){
        //初始化属性,data,computed,props,watch等等
        initState(this)
    }
    
    function initState(vm) {
        //......
        if (opts.watch) {
            initWatch(this, vm.$options.watch);
        }
    }
    
    
    
    function initWatch(vm, watch) {   
    //遍历watch,为 每一个 watch添加订阅者就是user-watcher
        for (var key in watch) {    
            var watchOpt = watch[key];
            createWatcher(vm, key, handler);
        }
    }
    
    
    function createWatcher(
        vm,
        expOrFn,
        handler,
        options
      ) {
        //不同的watch写法,得到的hander也是不一样的
        if (isPlainObject(handler)) {
          options = handler;
          handler = handler.handler;
        }
        if (typeof handler === 'string') {
          handler = vm[handler];
        }
        //expOrFn是key ,handler是该key的监听回调,下面会很多次说起(监听回调)
        return vm.$watch(expOrFn, handler, options)
      }
    

    按步骤一步一步看下来 上面先遍历watch,后面给每个侦听属性添加一个user-watcher,其中传的参数expOrFn是key,handler是该key的监听回调,handler的取值可能会有几种情况,列出我们可能的watch形式。

        watch:{
            name:{
             handler(){},
            },
            name(){},
            name:"getNameWatch"
        }
    

    是一个对象时,就把该对象的handler赋值handler函数的话就直接赋值handler字符串就把vm.getNameWatch赋值给handler

    好了,之后我们看看$watcher发生了什么。

      Vue.prototype.$watch = function (
          expOrFn,
          cb,
          options
        ) {
          //下面会说
          var watcher = new Watcher(vm, expOrFn, cb, options);
          //立即执行一次该侦听wather
          if (options.immediate) {
              cb.call(vm, watcher.value);
          }
        };
    

    让我们快速吧视线移到new Watcher(),就是给每个侦听属性添加的user-watcher,看下Watcher源码,我会针对该知识,列重要的源码,就不累赘别的代码了。

    var Watcher = function (vm, key, cb, opt) {  
        this.vm = vm;    
        this.deep = opt.deep;    
        this.cb = cb;  
        // 下面这段主要是设置该key的监听回调
         this.getter = parsePath(expOrFn);
        };    
        // this.get 作用就是执行 this.getter()
        this.value = this.get();
    };
    
     function parsePath(path) {
        var segments = path.split('.');
        return function (obj) {
          for (var i = 0; i < segments.length; i++) {
            if (!obj) {
              return
            }
            obj = obj[segments[i]];
          }
          return obj
        }
      }
    

    parsePath主要返回了一个匿名函数,函数中的内容主要是会从vm上获取该侦听keyvalue,这样会发生依赖收集。 看看之后的执行吧,之后赋值给this.getter,之后执行this.get()就是执行this.getter(),执行了就会对该侦听属性进行依赖收集。说了这么多还是稍微多一个过程看吧。

    我们已经知道parsePath会返回该侦听属性的监听回调。接下里继续 执行this.get()方法。

    Watcher.prototype.get = function get() {
          //把当前的user-watcher设置为Dep.target
         pushTarget(this);
         //把vm传进去,执行监听的回调,之后如果回调中有依赖的响应会触发它的依赖收集user-watcher。
         value = this.getter.call(vm, vm);
        var vm = this.vm;
          if (this.deep) {
            traverse(value);
          popTarget();
        }
        return value
      };
    
    

    value = this.getter.call(vm, vm); 这段会依赖收集watcher中的 key的订阅者,此时Dep.target是 user-watcher所以会被收集到subs数组中。

    之后返回this.get()返回到this.value,再退到上面就是Vue.prototype.$watchnew Watcher()返回的watcher,再判断immediate是否为true表示立即执行一次该keyhandler回调啦 。接着initWatch就大功告成了。

    之后在响应数据发生变化的时候就会派发更新,执行update就会执行user-watcher的监听回调啦啦啦!


    起源地下载网 » 梳理一下你脑子中vue的watch源码!!!

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元