const reactiveMap = new WeakMap();
//reactive入口函数⭐️⭐️⭐️⭐️⭐️
function reactive(target) {
// if trying to observe a readonly proxy, return the readonly version.
if (target && target["__v_isReadonly" /* IS_READONLY */]) {
return target;
}
return createReactiveObject(target, false, mutableHandlers, mutableCollectionHandlers);//⭐️⭐️⭐️⭐️⭐️mutableHandlers 和 mutableCollectionHandlers对象注意
}
//创建一个recativeobject函数⭐️⭐️⭐️⭐️⭐️
function createReactiveObject(target, isReadonly, baseHandlers, collectionHandlers) {
if (!isObject(target)) {//⭐️判断是不是对象
{
(`value cannot be made reactive: ${String(target)}`);
}
return target;
}
// target is already a Proxy, return it.
// exception: calling readonly() on a reactive object
if (target["__v_raw" /* RAW */] &&
!(isReadonly && target["__v_isReactive" /* IS_REACTIVE */])) {
return target;
}
// target already has corresponding Proxy
const proxyMap = reactiveMap;//⭐️弱对象赋值
const existingProxy = (target);//⭐️查看target对象是否在缓存中
if (existingProxy) {
return existingProxy;
}
// only a whitelist of value types can be observed.
const targetType = getTargetType(target);//⭐️获取target对象类型,实现代码见下
if (targetType === 0 /* INVALID */) {
return target;
}
const proxy = new Proxy(target, targetType === 2 /* COLLECTION */ ? collectionHandlers : baseHandlers);//⭐️new了一个proxy
(target, proxy);//⭐️存储弱对象中
return proxy;
}
//⭐️⭐️⭐️⭐️⭐️获取Target类型
function getTargetType(value) {
return value["__v_skip" /* SKIP */] || !(value)
? 0 /* INVALID */
: targetTypeMap(toRawType(value));
}
//⭐️⭐️⭐️⭐️⭐️类型判断具体实现
function targetTypeMap(rawType) {
switch (rawType) {
case 'Object':
case 'Array':
return 1 /* COMMON */;
case 'Map':
case 'Set':
case 'WeakMap':
case 'WeakSet':
return 2 /* COLLECTION */;
default:
return 0 /* INVALID */;
}
}
//⭐️⭐️toRawType
const toTypeString = (value) => (value);
const toRawType = (value) => {
// extract "RawType" from strings like "[object RawType]"
return toTypeString(value).slice(8, -1);
};
const mutableHandlers = {
get,
set,
deleteProperty,
has,
ownKeys
};
const get = function createGetter(isReadonly = false, shallow = false) {
return function get(target, key, receiver) {
if (key === "__v_isReactive" /* IS_REACTIVE */) {
return !isReadonly;
}
else if (key === "__v_isReadonly" /* IS_READONLY */) {
return isReadonly;
}
else if (key === "__v_raw" /* RAW */ &&
receiver === (isReadonly ? readonlyMap : reactiveMap).get(target)) {
return target;
}
const targetIsArray = isArray(target);
if (!isReadonly && targetIsArray && hasOwn(arrayInstrumentations, key)) {
return (arrayInstrumentations, key, receiver);
}
const res = (target, key, receiver);
if (isSymbol(key)
? (key)
: key === `__proto__` || key === `__v_isRef`) {
return res;
}
if (!isReadonly) {
track(target, "get" /* GET */, key);
}
if (shallow) {
return res;
}
if (isRef(res)) {
// ref unwrapping - does not apply for Array + integer key.
const shouldUnwrap = !targetIsArray || !isIntegerKey(key);
return shouldUnwrap ? : res;
}
if (isObject(res)) {
// Convert returned value into a proxy as well. we do the isObject check
// here to avoid invalid value warning. Also need to lazy access readonly
// and reactive here to avoid circular dependency.
return isReadonly ? readonly(res) : reactive(res);
}
return res;
};
}
const set = function createSetter(shallow = false) {
return function set(target, key, value, receiver) {
const oldValue = target[key];
if (!shallow) {
value = toRaw(value);
if (!isArray(target) && isRef(oldValue) && !isRef(value)) {
= value;
return true;
}
}
const hadKey = isArray(target) && isIntegerKey(key)
? Number(key) <
: hasOwn(target, key);
const result = (target, key, value, receiver);
// don't trigger if target is something up in the prototype chain of original
if (target === toRaw(receiver)) {
if (!hadKey) {
trigger(target, "add" /* ADD */, key, value);
}
else if (hasChanged(value, oldValue)) {
trigger(target, "set" /* SET */, key, value, oldValue);
}
}
return result;
};
}
function deleteProperty(target, key) {
const hadKey = hasOwn(target, key);
const oldValue = target[key];
const result = (target, key);
if (result && hadKey) {
trigger(target, "delete" /* DELETE */, key, undefined, oldValue);
}
return result;
}
function has(target, key) {
const result = (target, key);
if (!isSymbol(key) || !(key)) {
track(target, "has" /* HAS */, key);
}
return result;
}
function ownKeys(target) {
track(target, "iterate" /* ITERATE */, isArray(target) ? 'length' : ITERATE_KEY);
return (target);
}
const mutableCollectionHandlers = {
get: createInstrumentationGetter(false, false)
};
const hasOwnProperty = ;
const hasOwn = (val, key) => (val, key);
function createInstrumentationGetter(isReadonly, shallow) {
const instrumentations = shallow
? shallowInstrumentations
: isReadonly
? readonlyInstrumentations
: mutableInstrumentations;
return (target, key, receiver) => {
if (key === "__v_isReactive" /* IS_REACTIVE */) {
return !isReadonly;
}
else if (key === "__v_isReadonly" /* IS_READONLY */) {
return isReadonly;
}
else if (key === "__v_raw" /* RAW */) {
return target;
}
return (hasOwn(instrumentations, key) && key in target
? instrumentations
: target, key, receiver);
};
}