实现reactiveApi
function createGet(isReadonly = false, shallow = false) {
return function get(target, key, receiver) {
const res = Reflect.get(target, key, receiver);
if(!isReadonly) {
}
if(shallow) {
return res;
}
if(isObject(res)) {
return isReadonly ? readonly(res) : reactive(res);
}
return res;
}
}
function createSetter(shallow = false) {
return function set(target, key, value, receiver) {
const result = Reflect.set(target, key, value, receiver);
return result;
}
}
const get = createGet();
const shallowGet = createGet(false, true);
const readonlyGet = createGet(true);
const shallowReadonlyGet = createGet(true, true);
const set = createSetter();
const shallowSet = createSetter();
export const mutableHandlers = {
get,
set
};
export const shallowReactiveHandlers = {
get: shallowGet,
set: shallowSet
};
let readonlyObj = {
set(target, key) {
console.warn(`set ${key} falied`)
}
}
export const readonlyHandlers = Object.assign({
get: readonlyGet,
}, readonlyObj);
export const shallowReadonlyHandlers = Object.assign({
get: shallowReadonlyGet
}, readonlyObj);
import { isObject } from "@vue/shared";
import {
mutableHandlers,
shallowReactiveHandlers,
shallowReadonlyHandlers,
readonlyHandlers
} from './baseHandler'
export function reactive(target) {
return createReactiveObject(target, false, mutableHandlers);
}
export function shallowReactive(target) {
return createReactiveObject(target, false, shallowReactiveHandlers);
}
export function readonly(target) {
return createReactiveObject(target, true, readonlyHandlers);
}
export function shallowReadonly(target) {
return createReactiveObject(target, true, shallowReadonlyHandlers);
}
const reactiveMap = new WeakMap();
const readonlyMap = new WeakMap();
export function createReactiveObject(target, isReadonly, baseHandler) {
if(isObject(target)) {
return target;
}
const proxyMap = isReadonly ? readonlyMap : reactiveMap;
const exisitProxy = proxyMap.get(target)
if(exisitProxy) {
return exisitProxy;
}
const proxy = new Proxy(target, baseHandler);
proxyMap.set(target, proxy);
return proxy;
}
export const isObject = (value) => typeof value === 'object' && value !== null;
总结
- proxy进行数据的代理
- proxy只代理对象,get,set抽离的方式,让每个api对应的逻辑更加清晰
- 代理的逻辑要考虑它们是不是 只读的 或者 是不是浅层代理的
- 代理的时候,代理过的对象,不用继续代理,我们就需要用 一个桶的概念去进行管理,WeakMap是最适合的,key是对象,会自动垃圾回收
- 通过 是否是只读的 指定对应的桶(类似于垃圾分类)