关于前端:微型Vue框架实现Part2数据代理实现

数据代理实现的底层

  • 应用Object.defineProperty()

object类型的代理实现

  • 单纯的对象构造

     obj = {
       num: 20,
       name: 'xx'
     }
  • 对象嵌套对象的数据结构

     obj = {
       name: "xx",
       obj: {
          num: 20,
          age: 33
       }
     }
  • 代码实现

    /**
     * 代理数据对象
     */
    
    function getObjKey(obj) {
      return Object.keys(obj);
    }
    function getNameSpace (nameSpace, key) {
      if (key === null || key === "") {
          return nameSpace;
      }else if(nameSpace === null || nameSpace === "") {
          return key
      }else {
          return nameSpace + "." + key
      }
    }
    
    
    function constructObjProxy (vm, options, nameSpace){
      let proxyObj = { };
      
      const optionAllKey = getObjKey(options);
      optionAllKey.forEach((key, index) => {
        {
          /**
           * proxyObj对象 代理 options的key
           * 目标:监听data对象中的值
           */
          Object.defineProperty(proxyObj, key, {
              configurable: true,
              get: function() {
                  return options[key]
              },
              set: function(value) {
                  console.log("proxyObj对象代理——扭转的时候做点什么。。。");
    
                  options[key] = value;
              }
          })
        }
    
        {
          /**
           * vm实例 代理 options的key
           * 目标: vm实例能批改data中的指
           */
          Object.defineProperty(vm, key, {
              configurable: true,
              get: function() {
                  return options[key]
              },
              set: function(value) {
                  console.log("vm代理key——扭转时候做点什么。。。");
    
                  options[key] = value;
              }
          })
        }
    
        // 对象嵌套对象的状况
        if(options[key] instanceof Object) {
          options[key] = constructProxy(vm, options[key], getNameSpace(nameSpace, key))
        }
      })
    
      return proxyObj;
    }
    
    
    /**
     * 
     * @param {*} vm 实例对象
     * @param {*} options 须要代理的数据对象
     * @param {*} nameSpace 命名空间
     * 
     * 仅针对object、Array类型的数据进行代理
     */
    export  function constructProxy(vm, options, nameSpace) {
      let proxyObj = null;
      if(options instanceof Object) {
          proxyObj = constructObjProxy(vm, options, nameSpace)
      }else if( options instanceof Array) {
    
      }else {
          throw new Error("this is not proxy object");
      }
    
      return proxyObj
    }

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理