zoukankan      html  css  js  c++  java
  • vue源码解析data与watcher

    以一份简单的例子说明:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <script src='node_modules/vue/dist/vue.js' type='text/javascript'></script>
    
    </head>
    <body>
    <div id='app'></div>
    <script type='text/javascript'>
        var vueIns=new Vue({
          data(){
            return {
              aaa:1,
              bbb:2
            }
          },
          created(){
            this.aaa =3
          },
          methods:{
            confirm(){
              this.bbb=333
            }
          },
          template:'<div><h1>{{aaa}}</h1><h2>{{bbb}}</h2></div>'
        }).$mount('#app')
        console.log(vueIns)
    </script>
    </body>
    </html>

     Vue对象中的data对象

    Observer.prototype.walk = function walk (obj) {
        var keys = Object.keys(obj);
        for (var i = 0; i < keys.length; i++) {
          defineReactive$$1(obj, keys[i]);
        }
    };
    
    /**
     * Define a reactive property on an Object.
     */
      function defineReactive$$1 (
        obj,
        key,
        val,
        customSetter,
        shallow
      ) {
        var dep = new Dep();
    
        var property = Object.getOwnPropertyDescriptor(obj, key);
        if (property && property.configurable === false) {
          return
        }
    
        // cater for pre-defined getter/setters
        var getter = property && property.get;
        var setter = property && property.set;
        if ((!getter || setter) && arguments.length === 2) {
          val = obj[key];
        }
    
        var childOb = !shallow && observe(val);
        Object.defineProperty(obj, key, {
          enumerable: true,
          configurable: true,
          get: function reactiveGetter () {
            var value = getter ? getter.call(obj) : val;
            if (Dep.target) {
              dep.depend();
              if (childOb) {
                childOb.dep.depend();
                if (Array.isArray(value)) {
                  dependArray(value);
                }
              }
            }
            return value
          },
          set: function reactiveSetter (newVal) {
            var value = getter ? getter.call(obj) : val;
            /* eslint-disable no-self-compare */
            if (newVal === value || (newVal !== newVal && value !== value)) {
              return
            }
            /* eslint-enable no-self-compare */
            if (customSetter) {
              customSetter();
            }
            // #7981: for accessor properties without setter
            if (getter && !setter) { return }
            if (setter) {
              setter.call(obj, newVal);
            } else {
              val = newVal;
            }
            childOb = !shallow && observe(newVal);
            dep.notify();
          }
        });
      }

    将_data的数据进行遍历defineProperty

    得到:vm.aaa的形式

     

    _data:
       aaa: 3
       bbb: 2
       __ob__: Observer {value: {…}, dep: Dep, vmCount: 1}
       get aaa: ƒ reactiveGetter()
       set aaa: ƒ reactiveSetter(newVal)
       get bbb: ƒ reactiveGetter()
       set bbb: ƒ reactiveSetter(newVal)
    

    代理:proxy方法

    proxy(vm, "_data", key); 
    
    function proxy (target, sourceKey, key) {
        sharedPropertyDefinition.get = function proxyGetter () {
          return this[sourceKey][key]
        };
        sharedPropertyDefinition.set = function proxySetter (val) {
          this[sourceKey][key] = val;
        };
        Object.defineProperty(target, key, sharedPropertyDefinition);
      }
    

      得到

    aaa: 3
    bbb: 2
    
    __proto__: Object
       get aaa: ƒ proxyGetter()
       set aaa: ƒ proxySetter(val)
       get bbb: ƒ proxyGetter()
       set bbb: ƒ proxySetter(val)
    

      

    数据监控执行

    initWatch

     function initWatch (vm, watch) {
        for (var key in watch) {
          var handler = watch[key];
          if (Array.isArray(handler)) {
            for (var i = 0; i < handler.length; i++) {
              createWatcher(vm, key, handler[i]);
            }
          } else {
            createWatcher(vm, key, handler);
          }
        }
      }
    
      function createWatcher (
        vm,
        expOrFn,
        handler,
        options
      ) {
        if (isPlainObject(handler)) {
          options = handler;
          handler = handler.handler;
        }
        if (typeof handler === 'string') {
          handler = vm[handler];
        }
        return vm.$watch(expOrFn, handler, options)
      }
    
    
       Vue.prototype.$watch = function (
          expOrFn,
          cb,
          options
        ) {
          var vm = this;
          if (isPlainObject(cb)) {
            return createWatcher(vm, expOrFn, cb, options)
          }
          options = options || {};
          options.user = true;
          var watcher = new Watcher(vm, expOrFn, cb, options);
          if (options.immediate) {
            try {
              cb.call(vm, watcher.value);
            } catch (error) {
              handleError(error, vm, ("callback for immediate watcher "" + (watcher.expression) + """));
            }
          }
          return function unwatchFn () {
            watcher.teardown();
          }
        };
      }
    

     

  • 相关阅读:
    Excel添加读音(中英均可)
    java随机函数的使用
    Python3基础第六篇:列表生成式
    Python3基础第七篇:异常处理
    Python3基础第八篇:assert断言
    Python3基础第五篇:range()函数
    Python3基础第二篇:不可变序列操作
    Python3基础第十篇:字符串常用操作
    Python3基础第九篇:字符串格式化
    Python3基础第四篇:列表切片
  • 原文地址:https://www.cnblogs.com/heyinwangchuan/p/13788135.html
Copyright © 2011-2022 走看看