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
猜你喜欢
- vue keep-alive 2023-10-08
- jsPlumb+vue创建字段映射关系 2023-10-08
- 基于CORS实现WebApi Ajax 跨域请求解决方法 2023-02-14
- javascript 判断当前浏览器版本并判断ie版本 2023-08-08
- JS实现左侧菜单工具栏 2022-08-31
- 关于 html:如何从 css 表中删除边距和填充 2022-09-21
- 1 Vue - 简介 2023-10-08
- layui数据表格以及传数据方式 2022-12-13
- 深入浅析AjaxFileUpload实现单个文件的 Ajax 文件上传库 2022-12-15
- ajax实现输入提示效果 2023-02-14