8000 new · devazine/vue-analysis@27a40c8 · GitHub
[go: up one dir, main page]

Skip to content

Commit 27a40c8

Browse files
committed
new
1 parent 07aad72 commit 27a40c8

22 files changed

+2895
-1
lines changed

4-ref/4/baseHandlers.js

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
import { isObject, isArray, hasOwn, isIntegerKey, hasChanged, isSymbol } from './shared.js'
2+
import {
3+
reactive, readonly,
4+
toRaw, ReactiveFlags, proxyMap, readonlyMap, shallowReactiveMap, shallowReadonlyMap
5+
} from './reactive.js'
6+
import { track, trigger, ITERATE_KEY, pauseTracking, resetTracking } from './effect.js'
7+
8+
function createArrayInstrumentations() {
9+
const instrumentations = {};
10+
['includes', 'indexOf', 'lastIndexOf'].forEach(key => {
11+
instrumentations[key] = function (...args) {
12+
const arr = toRaw(this);
13+
for (let i = 0, l = this.length; i < l; i++) {
14+
track(arr, "get", i + '');
15+
}
16+
const res = arr[key](...args);
17+
if (res === -1 || res === false) {
18+
return arr[key](...args.map(toRaw));
19+
} else {
20+
return res;
21+
}
22+
};
23+
});
24+
25+
['push', 'pop', 'shift', 'unshift', 'splice'].forEach(key => {
26+
instrumentations[key] = function (...args) {
27+
pauseTracking();
28+
const res = toRaw(this)[key].apply(this, args);
29+
resetTracking();
30+
return res
31+
}
32+
})
33+
return instrumentations
34+
}
35+
36+
const arrayInstrumentations = createArrayInstrumentations();
37+
38+
const get = createGetter();
39+
const set = createSetter();
40+
41+
const builtInSymbols = new Set(
42+
Object.getOwnPropertyNames(Symbol)
43+
.map(key => (Symbol)[key])
44+
.filter(isSymbol)
45+
)
46+
47+
function createGetter(isReadonly = false, shallow = false) {
48+
return function get(target, key, receiver) {
49+
const targetFromMap = (isReadonly
50+
? shallow
51+
? shallowReadonlyMap
52+
: readonlyMap
53+
: shallow
54+
? shallowReactiveMap
55+
: proxyMap
56+
).get(target);
57+
58+
if (key === ReactiveFlags.IS_REACTIVE) {
59+
return !isReadonly
60+
} else if (key === ReactiveFlags.IS_READONLY) {
61+
return isReadonly
62+
} else if (key === ReactiveFlags.IS_SHALLOW) {
63+
return shallow
64+
} else if (key === ReactiveFlags.RAW && targetFromMap) {
65+
return target;
66+
}
67+
68+
const targetIsArray = isArray(target);
69+
70+
if (!isReadonly && targetIsArray && hasOwn(arrayInstrumentations, key)) {
71+
return Reflect.get(arrayInstrumentations, key, receiver)
72+
}
73+
74+
const res = Reflect.get(target, key, receiver);
75+
76+
if (isSymbol(key) && builtInSymbols.has(key)) {
77+
return res;
78+
}
79+
80+
if (!isReadonly) {
81+
track(target, key);
82+
}
83+
84+
if (shallow) {
85+
return res
86+
}
87+
88+
if (isObject(res)) {
89+
return isReadonly ? readonly(res) : reactive(res);
90+
}
91+
92+
return res;
93+
}
94+
}
95+
96+
function createSetter() {
97+
return function set(target, key, value, receiver) {
98+
let oldValue = target[key];
99+
value = toRaw(value);
100+
oldValue = toRaw(oldValue);
101+
102+
const hadKey = isArray(target) && isIntegerKey(key)
103+
? Number(key) < target.length
104+
: hasOwn(target, key);
105+
106+
const res = Reflect.set(target, key, value, receiver);
107+
if (!hadKey) {
108+
trigger(target, key, 'add', value)
109+
} else if (hasChanged(value, oldValue)) {
110+
trigger(target, key, 'set', value)
111+
}
112+
return res;
113+
}
114+
}
115+
116+
function has(target, key) {
117+
const res = Reflect.has(target, key);
118+
track(target, key);
119+
return res;
120+
}
121+
122+
function ownKeys(target) {
123+
const key = isArray(target) ? 'length' : ITERATE_KEY;
124+
track(target, key);
125+
return Reflect.ownKeys(target);
126+
}
127+
128+
function deleteProperty(target, key) {
129+
const hadKey = hasOwn(target, key);
130+
const res = Reflect.deleteProperty(target, key);
131+
if (res && hadKey) {
132+
trigger(target, key, 'delete');
133+
}
134+
return res
135+
}
136+
137+
138+
export const mutableHandlers = {
139+
get,
140+
set,
141+
deleteProperty,
142+
has,
143+
ownKeys
144+
}
145+
146+
const readonlyGet = createGetter(true);
147+
148+
export const readonlyHandlers = {
149+
get: readonlyGet,
150+
set(target, key) {
151+
console.warn(`Set operation on key "${String(key)}" failed: target is readonly.`)
152+
return true
153+
},
154+
deleteProperty(target, key) {
155+
console.warn(`Delete operation on key "${String(key)}" failed: target is readonly.`);
156+
return true
157+
}
158+
}
159+
160+
export const shallowReactiveHandlers = Object.assign(
161+
{},
162+
mutableHandlers,
163+
{
164+
get: createGetter(false, true),
165+
set: createSetter()
166+
}
167+
)
168+
169+
export const shallowReadonlyHandlers = Object.assign(
170+
{},
171+
readonlyHandlers,
172+
{
173+
get: createGetter(true, true)
174+
}
175+
)

0 commit comments

Comments
 (0)
0