VUE3.0-手写实现组合API

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);    }
(0)

相关推荐