目录
1、包含的功能及函数
- 1、包含的功能及函数
- 2、函数实现
- 3、函数调用
isRef、isReactive、isReadonly、isProxy、shallowReactive、reactive、shallowReadonly、readonly、shallowRef、ref
2、函数实现// 定义一个reactiveHandler处理对象 const reactiveHandler = { // 获取属性值 get(target, prop) { if (prop === '_is_reactive') return true; const result = Reflect.get(target, prop); console.log('拦截了读取数据', prop, result); return result; }, // 修改属性值或者是添加属性 set(target, prop, value) { const result = Reflect.set(target, prop, value); console.log('拦截了修改数据或者是添加属性', prop, value); return result; }, // 删除某个属性 deleteProperty(target, prop) { const result = Reflect.deleteProperty(target, prop); console.log('拦截了删除数据', prop); return result; } } // 01-------------------------------------- // shallowReactive // 定义一个shallowReactive函数,传入一个目标对象 function shallowReactive(target) { // 判断当前的目标对象是不是object类型(对象/数组) if (target && typeof target === 'object') { return new Proxy(target, reactiveHandler); } // 如果传入的数据是基本类型的数据,那么就直接返回 return target; } // 02-------------------------------------- // reactive // 定义一个reactive函数,传入一个目标对象 function reactive(target) { // 判断当前的目标对象是不是object类型(对象/数组) if (target && typeof target === 'object') { // 对数组或者是对象中所有的数据进行reactive的递归处理 // 先判断当前的数据是不是数组 if (Array.isArray(target)) { // 数组的数据要进行遍历操作0 target.forEach((item, index) => { // 如果数组中还有数组 // 使用递归 target[index] = reactive(item); }); } else { // 再判断当前的数据是不是对象 // 对象的数据也要进行遍历的操作 Object.keys(target).forEach(key => { target[key] = reactive(target[key]); }); } return new Proxy(target, reactiveHandler); } // 如果传入的数据是基本类型的数据,那么就直接返回 return target; } // =============================================================== // 定义了一个readonlyHandler处理器 const readonlyHandler = { get(target, prop) { if (prop === '_is_readonly') return true; const result = Reflect.get(target, prop); console.log('拦截到了读取数据了', prop, result); return result; }, set(target, prop, value) { console.warn('只能读取数据,不能修改数据或者添加数据'); return true; }, deleteProperty(target, prop) { console.warn('只能读取数据,不能删除数据'); return true; } } // 03-------------------------------------- // shallowReadonly // 定义一个shallowReadonly函数 function shallowReadonly(target) { // 需要判断当前的数据是不是对象 if (target && typeof target === 'object') { return new Proxy(target, readonlyHandler); } return target; } // 04-------------------------------------- // readonly // 定义一个readonly函数 function readonly(target) { // 需要判断当前的数据是不是对象 if (target && typeof target === 'object') { // 判断target是不是数组 if (Array.isArray(target)) { // 遍历数组 target.forEach((item, index) => { target[index] = readonly(item); }); } else { // 判断target是不是对象 // 遍历对象 Object.keys(target).forEach(key => { target[key] = readonly(target[key]); }); } return new Proxy(target, readonlyHandler); } // 如果不是对象或者数组,那么直接返回 return target; } // =============================================================== // 05-------------------------------------- // shallowRef // 定义一个shallowRef函数 function shallowRef(target) { return { // 保存target数据保存起来 _value: target, get value() { console.log('劫持到了读取数据'); return this._value; }, set value(val) { console.log('劫持到了修改数据,准备更新界面', val); this._value = val; } } } // 06-------------------------------------- // ref // 定义一个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('劫持到了修改数据,准备更新界面', val); this._value = val; } } } // =============================================================== // 定义一个函数isRef,判断当前的对象是不是ref对象 function isRef(obj) { return obj && obj._is_ref; } // 定义一个函数isReactive,判断当前的对象是不是reactive对象 function isReactive(obj) { return obj && obj._is_reactive; } // 定义一个函数isReadonly,判断当前的对象是不是readonly对象 function isReadonly(obj) { return obj && obj._is_readonly; } // 定义一个函数isProxy,判断当前的对象是不是reactive对象或者readonly对象 function isProxy(obj) { return isReactive(obj) || isReadonly(obj); }3、函数调用
// 01-------------------------------------- // shallowReactive const proxyUser1 = shallowReactive({ name: '小明', car: { color: 'red' } }); // 拦截到了读和写的数据 proxyUser1.name += '=='; // 拦截到了读取数据,但是拦截不到写的数据 proxyUser1.car.color + '=='; // 拦截到了删除数据 delete proxyUser1.name; // 只拦截到了读,但是拦截不到删除 delete proxyUser1.car.color; // 02-------------------------------------- // reactive const proxyUser2 = reactive({ name: '小明', car: { color: 'red' } }); // 拦截到了读和修改的数据 proxyUser2.name += '=='; // 拦截到了读和修改的数据 proxyUser2.car.color = '=='; // 拦截了删除 delete proxyUser2.name; // 拦截到了读和拦截到了删除 delete proxyUser2.car.color; // 03-------------------------------------- // shallowReadonly const proxyUser3 = shallowReadonly({ name: '小明', cars: ['奔驰', '宝马'] }); // 可以读取 console.log(proxyUser3.name); // 不能修改 proxyUser3.name = '=='; // 不能删除 delete proxyUser3.name; // 拦截到了读取,可以修改 proxyUser3.cars[0] = '奥迪'; // 拦截到了读取,可以删除 delete proxyUser3.cars[0]; // 04-------------------------------------- // readonly const proxyUser4 = readonly({ name: '小明', cars: ['奔驰', '宝马'] }); // 拦截到了读取 console.log(proxyUser4.name); console.log(proxyUser4.cars[0]); // 只读的 proxyUser4.name = '哈哈'; // 只读的 proxyUser4.cars[0] = '哈哈'; delete proxyUser4.name; delete proxyUser4.cars[0]; // 05-------------------------------------- // shallowRef const ref1 = shallowRef({ name: '小明', car: { color: 'red' } }); console.log(ref1.value); // 劫持到 ref1.value = '=='; // 劫持不到 ref1.value.car = '=='; // 06-------------------------------------- // ref const ref2 = ref({ name: '小明', car: { color: 'red' } }); console.log(ref2.value); // 劫持到 ref2.value = '=='; // 劫持到 ref2.value.car = '=='; // 07-------------------------------------- console.log(isRef(ref({}))); console.log(isReactive(reactive({}))); console.log(isReadonly(readonly({}))); console.log(isProxy(reactive({}))); console.log(isProxy(readonly({})));