1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
| // shallowReactive(浅的监视,浅的劫持,浅的响应数据) 与 reactive(深的) // shallowReadonly 与 readonly // shallowRef 与 ref // isRef, isReactive 与 isReadonly isProxy
// 定义一个handle对象 let handler = { // Reflect.get()方法与从对象 ( target[propertyKey]) 中读取属性类似, // 但它是通过一个函数执行来操作的。 // Reflect.get方法允许你从一个对象中取属性值 // Reflect.set 方法允许你在对象上设置属性
get(target, prop) { if(prop === '_is_reactive') return true let result = Reflect.get(target, prop) console.log('拦截了读取数据', prop, result); return result }, // prop:将被设置的属性名或Symbol。 value:新属性值 set(target, prop, value) { let result = Reflect.set(target, prop, value); console.log('拦截了修改数据或添加属性', prop, result); return result }, // target:目标对象 property:待删除的属性名 // deleteProperty必须返回一个Boolean类型的值,表示该属性是否被成功删除 deleteProperty(target, prop) { let result = Reflect.deleteProperty(target, prop) console.log('拦截了删除数据', prop, result); return result } }
// 定义一个 shallowReactive 函数,传入一个目标对象 function shallowReactive(target) { // 判断target类型是不是一个object类型(可能会传普通数据) // target instanceof Object if (target && typeof target === 'object') { return new Proxy(target, handler) } // 如果是基本数据类型,直接返回 return target } // 定义一个 reactive 函数,传入一个目标对象 function Reactive(target) { if (target && typeof target === 'object') { // 对数组或是对象中所有的数据进行 reactive 的递归处理(原因:reactive是深度响应式数据) // 1. 当前的数据是不是数组 // Array.isArray(target) if (target instanceof Array) { target.forEach((item, index) => { target[index] = Reactive(item) }) } else { // 2.再判断当前的数据是不是对象 // 对象的数据也要进行遍历操作 Object.keys(target).forEach(key => { target[key] = Reactive(target[key]) }) } return new Proxy(target, handler) } // 如果是基本数据类型,直接返回 return target }
// ============================= // 定义一个handlerReadonly 处理器 let handlerReadonly = { get(target, prop) { if(prop === '_is_readonly') return true let result = Reflect.get(target, prop) console.log('Readonly:拦截了读取数据', prop, result); return result }, set(target, prop, value) { // let result = Reflect.set(target, prop, value); console.warn('只能读取数据,不能修改数据'); return true }, deleteProperty(target, prop) { // let result = Reflect.deleteProperty(target, prop) console.warn('只能读取数据,不能删除数据'); return true } }
// 定义一个 shallowReadonly 函数 function shallowReadonly(target) { if (target && typeof target === 'object') { return new Proxy(target, handlerReadonly) } return target } // 定义一个 readonly 函数 function readonly(target) { if (target && typeof target === 'object') { if (target instanceof Array) { target.forEach((item, index) => { // 递归处理item target[index] = readonly(item) }) } else { Object.keys(target).forEach(key => { target[key] = readonly(target[key]) }) } return new Proxy(target, handlerReadonly) } return target }
// ==========================================
// 定义一个 shallowRef 函数 function shallowRef(target) { return { // 保存target _value: target, get value() { console.log('劫持到读取数据'); return this._value }, set value(val) { console.log('劫持到修改数据,准备更新界面',val); this._value = val }, } } // 定义一个 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 ,判断当前的对象是不是 readonly 对象 或 reactive 对象 function isProxy(obj) { return isReactive(obj) || isReadonly(obj) }
|