1.新建 index.js 页面
//shallowReactive (浅劫持) reactive 深的
const reactiveHandler = {
/* 获取属性 */
get(target, prop) {
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, result, value);
return result;
},
/* 删除 */
deleteProperty(target, prop) {
const result = Reflect.deleteProperty(target, prop);
console.log('拦截了删除属性', prop, result);
return result;
},
};
/* 定义一个shallowReactive函数 ,传入一个目标对象 */
function shallowReactive(target) {
//判断当前目标是不是object类型
if (target && typeof target == 'object') {
return new Proxy(target, reactiveHandler);
}
return target;
}
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, reactiveHandler);
}
return target;
}
//======================shallowReadonly /readonly====================================
const readOnlyHandler = {
get(target, prop) {
const result = Reflect.get(target, prop);
console.log('拦截到了读取数据:', target, prop);
return result;
},
set(target, prop, value) {
console.warn('只能读取数据,不能修改数据或者提添加数据');
return true;
},
deleteProperty(target, prop) {
console.warn('只能读取数据,不能删除数据');
return true;
},
};
//定义一个shallReadonly
function shallowReadonly(target) {
//需要判断当前数据是否是对象
if (target && typeof target == 'object') {
return new Proxy(target, readOnlyHandler);
}
//如果不是对象或者数组直接返回
return target;
}
//定义一个readonly函数
function readOnly(target) {
if (target && typeof target == 'object') {
//判断target是不是数组
if (Array.isArray(target)) {
target.forEach((item, index) => {
target[index] = readOnly(item);
});
} else {
Object.keys(target).forEach(item => {
target[item] = readOnly(target[item]);
});
}
return new Proxy(target, readOnlyHandler);
}
//如果不是对象或者数组直接返回
return target;
}
//======================shallowRef /ref====================================
function shallowRef(target) {
return {
_value: target,
get value() {
console.log('拦截到了读取数据');
return this._value;
},
set value(val) {
console.log('拦截到了修改数据', val);
this._value = val;
},
};
}
function ref(target) {
target = reactive(target);
return {
_value: target,
get value() {
console.log('拦截到了读取数据');
return this._value;
},
set value(val) {
console.log('拦截到了修改数据', val);
this._value = val;
},
};
}
2.HTML 页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="index.js"></script>
<script>
//=========shallowReactive/reactive===================
let proxyObj1 = shallowReactive({
name: '张三',
car: {
color: 'red',
},
});
//拦截到了读和修改数据
// proxyObj1.name += '李四';
//只拦截到了读,没有拦截到修改
//proxyObj1.car.color = +'ddd';
//只拦截到了读,没有拦截到删除
//delete proxyObj1.car.color;
let proxyObj2 = reactive({
name: '张三',
car: {
color: 'red',
},
});
//拦截到了读和修改数据
//proxyObj2.name += '李四';
//拦截到了读数据 和修改数据
//proxyObj2.car.color = +'ddd';
//拦截到了读数据,和删除数据
//delete proxyObj2.car.color;
//=========shallowReadonly/readonly===================
let proxyObj3 = shallowReadonly({
name: '张三',
color: ['red', 'yellow'],
});
//拦截到了读取数据不能修改
// proxyObj3.name += '==';
//拦截到了读取数据
//console.log(proxyObj3.name);
// console.log(proxyObj3.color[0]);
//拦截到了读取数据,不能删除数据
//delete proxyObj3.name;
//拦截到了只能读取数据,不能删除数据
// proxyObj3.color[0] = 'green';
//拦截到了读取数据 ,拦截不了深度删除
//delete proxyObj3.color[0];
let proxyObj4 = readOnly({
name: '张三',
color: ['red', 'yellow'],
});
//拦截到了读取数据 不能修改数据或者提添加数据
// proxyObj4.name += '==';
//拦截到了读取数据
// console.log(proxyObj4.name);
//拦截到了读取数据
// console.log(proxyObj4.color[0]);
//拦截到了只能读取数据,不能删除数据
// delete proxyObj4.name;
//拦截到了只能读取数据,不能删除数据
// delete proxyObj4.color[0];
//拦截到了只能读取数据,不能修改数据或者提添加数据
//proxyObj4.color[0] = 'green';
//=========shallowRef/ref===================
let ref1 = shallowRef({
name: '张三',
car: {
color: 'red',
},
});
//拦截到了读取数据
// console.log(ref1.value);
//拦截到了修改数据 ==
//ref1.value += '==';
//拦截到了读取数据,无法修改
//ref1.value.car = '==';
let ref2 = ref({
name: '张三',
car: {
color: 'red',
},
});
//拦截到了读取数据
// console.log(ref2.value);
//拦截到了修改数据 ==
//ref2.value += '==';
//拦截到了读取数据,截取到了修改数据
ref2.value.car = '==';
</script>
</head>
<body></body>
</html>