沃梦达 / IT编程 / 前端开发 / 正文

VUE3.0-手写实现组合API

1.shallowReactive 与 reactive1.1shallowReactive-浅监听// 定义一个shallowReactive函数,传入一个目标对象function shallowReactive(target) {// 判断当前的目标对象是不是object类型(对象/数组)if (target t...

1.shallowReactive 与 reactive

1.1shallowReactive-浅监听

	// 定义一个shallowReactive函数,传入一个目标对象
    function shallowReactive(target) {
      // 判断当前的目标对象是不是object类型(对象/数组)
      if (target && typeof target === 'object') {
        return new Proxy(target, {
          // 获取属性值
          get(obj, key) {
            console.log('拦截了get');
            if(key=='_is_reactive'){
            	return true
            };
            return Reflect.get(obj, key);
          },
          // 修改属性值或者添加属性
          set(obj, key, value) {
            console.log('拦截了set');
            return Reflect.set(obj, key, value);
          },
          // 删除某个属性
          deleteProperty(obj, key) {
            console.log('拦截了deleteProperty');
            return Reflect.deleteProperty(obj, key);
          }
        })
      }
      // 如果传入的是基本数据类型,那么就直接返回
      return target;
    };

     let user = shallowReactive({
       name: '张三',
       wife: {
         name: '张三老婆'
       }
     });
    // 拦截到了读和写的数据
     console.log(user.name);
     user.name = '李四';
     console.log(user.name);


    // 拦截到了读取的数据,但是拦截不到写的数据
     user.wife.name = '张三媳妇';
     console.log(user.wife.name);

    // 拦截到了删除数据
     delete user.name;

    // 只拦截到了读,但是拦截不到删除
     delete user.wife.name

1.2reactive-深监听

	// 定义一个reactive函数,传入一个目标对象
    function reactive(target) {
      // 判断当前的目标对象是不是object类型(对象/数组)
      if (target && typeof target === 'object') {
        // 对数组/对象中所有的数据进行reactive的递归处理
        // 判断当前的数据是不是数组
        if (Array.isArray(target)) {
          target.forEach((item, index) => {
            // 数组的数据要进行遍历操作
            target[index] = reactive(item);
          })
        } else {
          // 判断当前的数据是不是对象
          Object.keys(target).forEach(key => {
            target[key] = reactive(target[key]);
          })
        }
        return new Proxy(target, {
          // 获取属性值
          get(obj, key) {
            console.log('拦截了get');
            if(key=='_is_reactive'){
            	return true
            };
            return Reflect.get(obj, key);
          },
          // 修改属性值或者添加属性
          set(obj, key, value) {
            console.log('拦截了set');
            return Reflect.set(obj, key, value);
          },
          // 删除某个属性
          deleteProperty(obj, key) {
            console.log('拦截了deleteProperty');
            return Reflect.deleteProperty(obj, key);
          }
        })
      }
      // 如果传入的是基本数据类型,那么就直接返回
      return target;
    };
    
    let user = reactive({
      name: '张三',
      wife: {
        name: '张三老婆'
      }
    });

    // 拦截到了读写的数据
     console.log(user.name);
     user.name = '李四';
     console.log(user.name);

    // 拦截到了读写的数据
     console.log(user.wife.name);
     user.wife.name = '张三媳妇';
     console.log(user.wife.name);

    // 拦截到了删除的数据
     delete user.name;

    // 拦截到了删除的数据
    delete user.wife.name

shallowReadonly 与 readonly

shallowReadonly

    // 定义一个shallowReadonly函数
    function shallowReadonly(target) {
      // 判断当前的数据是不是对象
      if (target && typeof target === 'object') {
        return new Proxy(target, {
          get(obj, key) {
            console.log('拦截到get了');
            if(key=='_is_readonly'){
            	return true
            };
            return Reflect.get(obj, key);
          },
          set(obj, key, value) {
            console.warn('只能读取数据,不能修改数据或者添加数据');
            return true;
          },
          deleteProperty(obj, key) {
            console.log('只能读取数据,不能删除数据');
            return true;
          }
        })
      };
      return target;
    };

	let user = shallowReadonly({
      name: '张三',
      likes: ['篮球', '足球']
    });
    // 可以读取
    console.log(user.name);
    // 不能修改
    user.name = '李四';
    // 不能删除
    delete user.name;

    // 可以读取
    console.log(user.likes[0]);
    // 拦截到了读取,可以修改
    user.likes[0] = '羽毛球';
    // 拦截到了读取,可以删除
    delete user.likes[0];

readonly

    // 定义一个readonly函数
    function readonly(target) {
      // 判断当前的数据是不是对象
      if (target && typeof target === 'object') {
        if (Array.isArray(target)) {// 判断是不是数组
          target.forEach((item, index) => {
            target[index] = readonly(item);
          })
        } else {// 判断是不是对象
          Object.keys(target).forEach(key => {
            target[key] = readonly(target[key])
          })
        }
        return new Proxy(target, {
          get(obj, key) {
            console.log('拦截到get了');
            if(key=='_is_readonly'){
            	return true
            };
            return Reflect.get(obj, key);
          },
          set(obj, key, value) {
            console.warn('只能读取数据,不能修改数据或者添加数据');
            return true;
          },
          deleteProperty(obj, key) {
            console.log('只能读取数据,不能删除数据');
            return true;
          }
        })
      };
      return target;
    };

    let user = readonly({
      name: '张三',
      likes: ['篮球', '足球']
    });
    // 可以读取
    console.log(user.name);
    // 不能修改
    user.name = '李四';
    // 不能删除
    delete user.name;

    // 可以读取
    console.log(user.likes[0]);
    // 拦截到了读取,不可以修改
    user.likes[0] = '羽毛球';
    // 拦截到了读取,不可以删除
    delete user.likes[0];

shallowRef 与 ref

shallowRef

  // 定义一个shallowRef函数
    function shallowRef(target) {
      return {
        _is_ref: true, // 用来标识是ref对象
        // 保存target数据
        _value: target,
        get value() {
          console.log('劫持到了读取数据');
          return this._value;
        },
        set value(val) {
          console.log('劫持到了修改/设置数据');
          this._value = val;
        }
      }
    };
    let user = shallowRef({
      name: '张三',
      wife: {
        name: '张三老婆'
      }
    });

    // 劫持到了读取数据
    console.log(user.value);

    // 劫持到了修改数据
    user.value = {
      name: '李四',
      wife: {
        name: '李四老婆'
      }
    };

    // 劫持到了读取数据,劫持不到修改数据
    user.value.wife = '张三媳妇'

ref

	// 定义一个reactive函数,传入一个目标对象
    function reactive(target) {
      // 判断当前的目标对象是不是object类型(对象/数组)
      if (target && typeof target === 'object') {
        // 对数组/对象中所有的数据进行reactive的递归处理
        // 判断当前的数据是不是数组
        if (Array.isArray(target)) {
          target.forEach((item, index) => {
            // 数组的数据要进行遍历操作
            target[index] = reactive(item);
          })
        } else {
          // 判断当前的数据是不是对象
          Object.keys(target).forEach(key => {
            target[key] = reactive(target[key]);
          })
        }
        return new Proxy(target, {
          // 获取属性值
          get(obj, key) {
            console.log('拦截了get');
            return Reflect.get(obj, key);
          },
          // 修改属性值或者添加属性
          set(obj, key, value) {
            console.log('拦截了set');
            return Reflect.set(obj, key, value);
          },
          // 删除某个属性
          deleteProperty(obj, key) {
            console.log('拦截了deleteProperty');
            return Reflect.deleteProperty(obj, key);
          }
        })
      }
      // 如果传入的是基本数据类型,那么就直接返回
      return target;
    };

    // 定义一个ref函数
    function ref(target) {
      target = reactive(target)
      return {
        _is_ref: true, // 用来标识是ref对象
        // 保存target数据
        _value: target,
        get value() {
          console.log('劫持到了读取数据');
          return this._value;
        },
        set value(val) {
          console.log('劫持到了修改/设置数据');
          this._value = val;
        }
      }
    };

    let user = ref({
      name: '张三',
      wife: {
        name: '张三老婆'
      }
    });

    // 劫持到了读取数据
    console.log(user.value);

    // 劫持到了修改数据
    user.value = {
      name: '李四',
      wife: {
        name: '李四老婆'
      }
    };

    // 劫持到了读取数据
    user.value.wife = '张三媳妇'

isRef , isReactive , isReadonly , isProxy

isRef

 	// 定义一个函数isRef,判断当前的对象是不是ref对象
    function isRef(obj) {
      return obj && obj._is_ref;
    };

isReactive

    // 定义一个函数isReactive,判断当前的对象是不是reactive对象
    function isReactive(obj) {
      return obj && obj._is_reactive;
    }

isReadonly

    // 定义一个函数isReadonly,判断当前的对象是不是readonly对象
    function isReadonly(obj) {
      return obj && obj._is_readonly;
    }

isProxy

    // 定义一个函数isProxy,判断当前的对象是不是reactive对象或者是readonly对象
    function isReadonly(obj) {
      return isReactive(obj) || isReadonly(obj);
    }

本文标题为:VUE3.0-手写实现组合API