zoukankan      html  css  js  c++  java
  • vue(原理)_数据代理

     

    1、数据代理:一个对象(A)来代理对另一个对象(B)的属性操作(A一定要包含B)

    2、vue中的数据代理:用vm实例对象来代替data 对data中的数据进行操作

      (1)vm实例代替data对象操作data对象中的name

        <div id="app">        
        </div>
        <script type="text/javascript" src="./vue.js"></script>
        <script type="text/javascript">
            const vm = new Vue({
                el:'#app',
                data:{
                    name:'xxm'
                }
            })
            console.log(vm.name) //vm对象代替data对象读取name,
            vm.name='szz' //vm对象代替data对象操作修改name 的值
            console.log(vm)
        </script>

      (2)分析:在控制台中打印输出vm实例如下

    vm实例对象中有_data对象里面存的是属性,而在外面又有age,name属性,通过调用vm里面的get()和set()方法就可以代理data对象,对data对象里面的属性进行操作

     

     3、github上有个大佬仿vue实现了mvvm库,下面通过mvvm库来分析vue源码中的数据代理

           地址:https://github.com/DMQ/mvvm

    <script type="text/javascript" src="./mvvm/mvvm.js"></script>
        <script type="text/javascript" src="./mvvm/compile.js"></script>
        <script type="text/javascript" src="./mvvm/observer.js"></script>
        <script type="text/javascript" src="./mvvm/watcher.js"></script>
        <script type="text/javascript">
            const vm = new MVVM({
                el:'#app',
                data:{
                    name:'xxm',
                    age:18
                }
    
            })
            console.log(vm.name) //vm对象代替data对象读取name,
            vm.name='szz' //vm对象代替data对象操作修改name 的值
            console.log(vm)

    4、调试:

    (1)第一步:在实例vm上添加断点

     (2)第二步:点击右侧 "↓" 调试进入mvvm.js函数库,进入MVVM函数库继续单步调试

     (3)第三步:点击右侧“↓”,进入到代理函数

    (4)第四步:在加三个断点(get(), set())如下

    (5)第五步:点击全部执行

    (6)第六步:点击执行 console.log(vm.name) 会跳到mvvm.js函数库中,调用执行get()方法

     (7)第七步:继续单步调试,会执行下面这一句,然后set监视到属性,就会执行mvvm.js中的set()方法

     

    5、数据代理主要用到mvvm.js库

    /*
    相关于Vue的构造函数
     */
    function MVVM(options) {
      // 将选项对象保存到vm
      this.$options = options;
      // 将data对象保存到vm和datq变量中
      var data = this._data = this.$options.data;
      //将vm保存在me变量中
      var me = this;
      // 遍历data中所有属性
      Object.keys(data).forEach(function (key) { // 属性名: name
        // 对指定属性实现代理
        me._proxy(key);
      });
    
      // 对data进行监视
      observe(data, this);
    
      // 创建一个用来编译模板的compile对象
      this.$compile = new Compile(options.el || document.body, this)
    }
    
    MVVM.prototype = {
      $watch: function (key, cb, options) {
        new Watcher(this, key, cb);
      },
    
      // 对指定属性实现代理
      _proxy: function (key) {
        // 保存vm
        var me = this;
        // 给vm添加指定属性名的属性(使用属性描述)
        Object.defineProperty(me, key, {
          configurable: false, // 不能再重新定义
          enumerable: true, // 可以枚举
          // 当通过vm.name读取属性值时自动调用
          get: function proxyGetter() {
            // 读取data中对应属性值返回(实现代理读操作)
            return me._data[key];
          },
          // 当通过vm.name = 'xxx'时自动调用
          set: function proxySetter(newVal) {
            // 将最新的值保存到data中对应的属性上(实现代理写操作)
            me._data[key] = newVal;
          }
        });
      }
    };
    虽然现在走得很慢,但不会一直这么慢
  • 相关阅读:
    TypeScript学习笔记(七):模块
    TypeScript学习笔记(六):泛型
    TypeScript学习笔记(五):接口
    TypeScript学习笔记(四):函数
    TypeScript学习笔记(三):类
    TypeScript学习笔记(二):基本数据类型及数据转换
    TypeScript学习笔记(一):介绍及环境搭建
    Egret的VS环境搭配
    [U3D Demo] 手机飞机大战
    Unity3D之UGUI学习笔记(三):EventSystem
  • 原文地址:https://www.cnblogs.com/xxm980617/p/10890093.html
Copyright © 2011-2022 走看看