//类型判断函数
const isObject = (val) => val !== null && typeof val === 'object';
const isArray = Array.isArray;
const isSymbol = (val) => typeof val === 'symbol';
const objectToString = Object.prototype.toString;
function isRef(r) {
return Boolean(r && r.__v_isRef === true);
}
const isString = (val) => typeof val === 'string';
//传入的key 必须是一个string类型的数据
const isIntegerKey = (key) => isString(key) &&key !== 'NaN' &&key[0] !== '-' &&'' + parseInt(key, 10) === key;
const hasOwnProperty = Object.prototype.hasOwnProperty;
const hasOwn = (val, key) => hasOwnProperty.call(val, key);
function getTargetType(value) {
return value["__v_skip" /* SKIP */] || !Object.isExtensible(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 */;
}
}
const toRawType = (value) => {
// extract "RawType" from strings like "[object RawType]"
return toTypeString(value).slice(8, -1);
};
const toTypeString = (value) => objectToString.call(value);
const reactiveMap = new WeakMap();
const set = createSetter();
//这样返回到 set 的时候就是一个函数
function toRaw(observed) {
const raw = observed && observed["__v_raw" /* RAW */];
return raw ? toRaw(raw) : observed;
}
function createSetter(shallow = false) {
//set 拦截操作 传入true时
return function set(target, key, value, receiver) {
let oldValue = target[key];
console.log(target,'target') // {a: 2}a: 2[[Prototype]]: Object
console.log(key,'key')
console.log(value,'value')
console.log(receiver,'receiver')
console.log(oldValue,'oldValue')
// !!!这一步是shallowReactive 和 reactive 区别
//因为它们传入 shallow的值不同
if (!shallow) {
//reactive createSetter()没有传参,所以shallow默认参数为false,
//所以走这个判断 把value 和oldValue 都转换为原始值
value = toRaw(value);
oldValue = toRaw(oldValue);
console.log(!isArray(target),'!isArray(target)') //true
console.log(isRef(oldValue),'isRef(oldValue)') //false
console.log(!isRef(value),'!isRef(value)') //true
//所以这个判断并没有为真,所以value的值也没有付给oldValue
if (!isArray(target) && isRef(oldValue) && !isRef(value)) {
oldValue.value = value;
return true;
}
}
//hadKey 为false
const hadKey = isArray(target) && isIntegerKey(key)
? Number(key) < target.length
: hasOwn(target, key);
console.log(hadKey,'handKey') //控制输出为真
//执行Reflect.set()操作
const result = Reflect.set(target, key, value, receiver);
console.log(result,'Reflect.set()后的值')
// don't trigger if target is something up in the prototype chain of original
//如果目标是原型链中的某个东西,则不要触发 所以我们需要调用toRaw() 转换为原始数据,这个地方是做异常处理的
console.log(target)
console.log(Object.getPrototypeOf(target),'原型链')
// console.log(target === toRaw(receiver),'2')
// console.log(target === toRaw(receiver),'2')
// console.log(target === toRaw(receiver),'2') //这个地方执行了 toRaw()函数改变了receiver 就会被Proxy get()所拦截
if (target === toRaw(receiver)) {
console.log('true login')
if (!hadKey) {
console.log(!hadKey,'!hadKey')
trigger(target, "add" /* ADD */, key, value);
}
else if (hasChanged(value, oldValue)) {
console.log('has changed')
trigger(target, "set" /* SET */, key, value, oldValue);
}
}
return result;
};
}
const hasChanged = (value, oldValue) => !Object.is(value, oldValue);
const get = createGetter();
const mutableHandlers = {
get, //get 和之前readOnly get方法差不多
set, //先实现set
deleteProperty, //实现set的基础上继续实现deleteProperty
has, //实现 has功能
ownKeys
};
const ITERATE_KEY = Symbol('iterate');
function ownKeys(target) {
track(target, "iterate" , isArray(target) ? 'length' : ITERATE_KEY);
return Reflect.ownKeys(target);
}
const arrayInstrumentations = createArrayInstrumentations();
// 创建数组仪表清单
function createArrayInstrumentations() {
const instrumentations = {};
['includes', 'indexOf', 'lastIndexOf'].forEach(key => {
instrumentations[key] = function (...args) {
const arr = toRaw(this);
for (let i = 0, l = this.length; i < l; i++) {
track(arr, "get" /* GET */, i + '');
}
// we run the method using the original args first (which may be reactive)
const res = arr[key](...args);
if (res === -1 || res === false) {
// if that didn't work, run it again using raw values.
return arr[key](...args.map(toRaw));
}
else {
return res;
}
};
});
['push', 'pop', 'shift', 'unshift', 'splice'].forEach(key => {
instrumentations[key] = function (...args) {
pauseTracking();
//拦截元素属性value的proxy
const res = toRaw(this)[key].apply(this, args);
resetTracking();
return res;
};
});
return instrumentations;
}
function pauseTracking() {
trackStack.push(shouldTrack);
shouldTrack = false;
}
function resetTracking() {
const last = trackStack.pop();
shouldTrack = last === undefined ? true : last;
}
const isNonTrackableKeys = makeMap(`__proto__,__v_isRef,__isVue`);
function makeMap(str, expectsLowerCase) {
const map = Object.create(null);
const list = str.split(',');
for (let i = 0; i < list.length; i++) {
map[list[i]] = true;
}
return expectsLowerCase ? val => !!map[val.toLowerCase()] : val => !!map[val];
}
function track(target, type, key) {
//这个地方实际上是返回了的,可能这个要在传入es6新增加的 weak 类型的obj 才会触发
if (!isTracking()) {
return;
}
let depsMap = targetMap.get(target);
if (!depsMap) {
targetMap.set(target, (depsMap = new Map()));
}
let dep = depsMap.get(key);
if (!dep) {
depsMap.set(key, (dep = createDep()));
}
const eventInfo = { effect: activeEffect, target, type, key }
;
trackEffects(dep, eventInfo);
}
let activeEffect;
let shouldTrack = true;
const trackStack = [];
function isTracking() {
return shouldTrack && activeEffect !== undefined;
}
function trackEffects(dep, debuggerEventExtraInfo) {
let shouldTrack = false;
if (effectTrackDepth <= maxMarkerBits) {
if (!newTracked(dep)) {
dep.n |= trackOpBit; // set newly tracked
shouldTrack = !wasTracked(dep);
}
}
else {
// Full cleanup mode.
shouldTrack = !dep.has(activeEffect);
}
if (shouldTrack) {
dep.add(activeEffect);
activeEffect.deps.push(dep);
if (activeEffect.onTrack) {
activeEffect.onTrack(Object.assign({
effect: activeEffect
}, debuggerEventExtraInfo));
}
}
}
//这一次没有传入参数,默认就都为false
function createGetter(isReadonly = false, shallow = false) {
// get 拦截操作
return function get(target, key, receiver) {
console.log('-----拦截------') //控制台输出12次
console.log(target,'target')
console.log(key,'key')
console.log(receiver,'receiver')
console.log(trackStack,'栈列表')
if (key === "__v_isReactive" /* IS_REACTIVE */) {
console.log('key === _v_isReactive 已经被执行返回了')
return !isReadonly;
}
else if (key === "__v_isReadonly" /* IS_READONLY */) {
console.log('key === _v_isReadonly 已经被执行返回了')
return isReadonly;
}
else if (key === "__v_raw" /* RAW */ &&
receiver ===
(isReadonly
? shallow
? shallowReadonlyMap
: readonlyMap
: shallow
? shallowReactiveMap
: reactiveMap).get(target)) {
console.log(reactiveMap,'reactiveMap')
console.log('走到这一步')
return target;
}
const targetIsArray = isArray(target);
if (!isReadonly && targetIsArray && hasOwn(arrayInstrumentations, key)) {
console.log(key,'key为数组操作方法')
console.log(arrayInstrumentations,'arrayInStrumentations')
return Reflect.get(arrayInstrumentations, key, receiver);
}
//拦截
const res = Reflect.get(target, key, receiver);
console.log(res,'Reflect.get()操作')
if (isSymbol(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) {
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.value : 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;
};
}
function has(target, key) {
const result = Reflect.has(target, key);
if (!isSymbol(key) || !builtInSymbols.has(key)) {
track(target, "has" /* HAS */, key);
}
return result;
}
//deleteProperty 函数看起来很简单
function deleteProperty(target, key) {
const hadKey = hasOwn(target, key);
const oldValue = target[key];
const result = Reflect.deleteProperty(target, key);
console.log(result,'result') //true
console.log(hadKey,'hadKey') //true
//函数就会执行trigger() 函数
if (result && hadKey) {
trigger(target, "delete", key, undefined, oldValue);
}
return result;
}
const targetMap = new WeakMap();
function trigger(target, type, key, newValue, oldValue, oldTarget) {
const depsMap = targetMap.get(target);
// console.log(targetMap,'targetMap的值')
console.log(depsMap,'depsMap 的值') //undefined
if (!depsMap) {
// never been tracked
//直接返回 没有继续执行下面的代码
return;
}
let deps = [];
if (type === "clear" /* CLEAR */) {
// collection being cleared
// trigger all effects for target
deps = [...depsMap.values()];
}
else if (key === 'length' && isArray(target)) {
depsMap.forEach((dep, key) => {
if (key === 'length' || key >= newValue) {
deps.push(dep);
}
});
}
else {
// schedule runs for SET | ADD | DELETE
if (key !== void 0) {
deps.push(depsMap.get(key));
}
// also run for iteration key on ADD | DELETE | Map.SET
switch (type) {
case "add" /* ADD */:
if (!isArray(target)) {
deps.push(depsMap.get(ITERATE_KEY));
if (isMap(target)) {
deps.push(depsMap.get(MAP_KEY_ITERATE_KEY));
}
}
else if (isIntegerKey(key)) {
// new index added to array -> length changes
deps.push(depsMap.get('length'));
}
break;
case "delete" /* DELETE */:
if (!isArray(target)) {
deps.push(depsMap.get(ITERATE_KEY));
if (isMap(target)) {
deps.push(depsMap.get(MAP_KEY_ITERATE_KEY));
}
}
break;
case "set" /* SET */:
if (isMap(target)) {
deps.push(depsMap.get(ITERATE_KEY));
}
break;
}
}
const eventInfo = { target, type, key, newValue, oldValue, oldTarget }
;
if (deps.length === 1) {
if (deps[0]) {
{
triggerEffects(deps[0], eventInfo);
}
}
}
else {
const effects = [];
for (const dep of deps) {
if (dep) {
effects.push(...dep);
}
}
{
triggerEffects(createDep(effects), eventInfo);
}
}
}
function reactive(target) {
// if trying to observe a readonly proxy, return the readonly version
//如果已经是readOnly对象了,就直接返回就行了,不需要再进行reactive处理
if (target && target["__v_isReadonly" /* IS_READONLY */]) {
return target;
}
// return createReactiveObject(target, false, mutableHandlers, mutableCollectionHandlers, reactiveMap);
//一般不走上边那个 所以下面只要传一个baseHandeler 就行了
return createReactiveObject(target, false, mutableHandlers, reactiveMap);
}
// function shallowReactive(target) {
// return createReactiveObject(target, false, shallowReactiveHandlers, shallowCollectionHandlers, shallowReactiveMap);
// }
// baseHandlers 传入的值 为 mutableHandlers
function createReactiveObject(target, isReadonly, baseHandlers, proxyMap) {
//传入isReadonly 值为true,判断传入的值是否为除Null 以外的Object对象,如果不是的话就会弹出错误,
if (!isObject(target)) {
{
console.warn(`value cannot be made reactive: ${String(target)}`);
}
return target;
}
// target is already a Proxy, return it.
// exception: calling readonly() on a reactive object
// 这些条件都满足的话说明传入的已经是一个reactive对象了 ,直接return 返回即可
if (target["__v_raw" /* RAW */] &&!(isReadonly && target["__v_isReactive" /* IS_REACTIVE */])) {
return target;
}
// 初始化时proxyMap 为空
console.log(proxyMap,'proxymap') //WeakMap { <items unknown> } proxymap
const existingProxy = proxyMap.get(target); //获取到的值为undefined
if (existingProxy) {
return existingProxy;
}
// only a whitelist of value types can be observed.
const targetType = getTargetType(target); //target为object时 targetType 为 1 如果tarfetType 为0时 数据类型不对
if (targetType === 0 /* INVALID */) {
return target;
}
console.log(targetType,'targetType')
const proxy = new Proxy(target, baseHandlers);
proxyMap.set(target, proxy);
return proxy;
}
// var result = reactive([{a:2},2,3])
// console.log(result[0],'取到的值') //Proxy {a: 2} "取到的值"
// var result = reactive([1,2,3])
// console.log(result[0],'取到的值') // 1 "取到的值"
// var result = reactive([1,2,3])
// console.log(result,'修改之前的值')
// result.shift()
// console.log(result,'修改之后的值')
var result = reactive({a:2})
console.log(result,'修改之前的值')
result.a=3
console.log(result,'修改之后的值')
控制台输出
const shallowReactiveMap = new WeakMap();
const shallowGet = createGetter(false, true);
const shallowSet = createSetter(true);
const shallowReactiveHandlers = extend({}, mutableHandlers, {
get: shallowGet, //重写get和 set这两个方法
set: shallowSet
});
function shallowReactive(target) {
return createReactiveObject(target, false, shallowReactiveHandlers, shallowReactiveMap);
}
var result = shallowReactive({a:2})
console.log(result,'修改之前的值')
result.a=3
console.log(result,'修改之后的值')