@feng3d/reactivity 1.0.5 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/RobotoMono-Medium-DVgDz_OO.woff2 +0 -0
- package/dist/assets/RobotoMono-Regular-BPoF81uy.woff2 +0 -0
- package/dist/assets/index-a2qCSG5V.css +629 -0
- package/dist/assets/index.html-Dyp3udP2.js +200 -0
- package/dist/assets/modulepreload-polyfill-DaKOjhqt.js +37 -0
- package/dist/assets/package-DuJynByc.js +2539 -0
- package/dist/assets/src//345/244/215/346/235/202/346/203/205/345/206/265/345/217/226/345/200/274/index.html-C3hbV3IR.js +59 -0
- package/dist/assets/src//346/225/260/347/273/204/index.html-CHK6WEhd.js +43 -0
- package/dist/docs/.nojekyll +1 -0
- package/dist/docs/assets/hierarchy.js +1 -0
- package/dist/docs/assets/highlight.css +92 -0
- package/dist/docs/assets/icons.js +18 -0
- package/dist/docs/assets/icons.svg +1 -0
- package/dist/docs/assets/main.js +60 -0
- package/dist/docs/assets/navigation.js +1 -0
- package/dist/docs/assets/search.js +1 -0
- package/dist/docs/assets/style.css +1640 -0
- package/dist/docs/classes/EffectScope.html +40 -0
- package/dist/docs/functions/batchRun.html +15 -0
- package/dist/docs/functions/computed.html +5 -0
- package/dist/docs/functions/effect.html +11 -0
- package/dist/docs/functions/effectScope.html +5 -0
- package/dist/docs/functions/forceTrack.html +6 -0
- package/dist/docs/functions/getCurrentScope.html +4 -0
- package/dist/docs/functions/isProxy.html +5 -0
- package/dist/docs/functions/isReactive.html +5 -0
- package/dist/docs/functions/isRef.html +5 -0
- package/dist/docs/functions/noTrack.html +6 -0
- package/dist/docs/functions/onScopeDispose.html +6 -0
- package/dist/docs/functions/reactive.html +19 -0
- package/dist/docs/functions/ref.html +13 -0
- package/dist/docs/functions/toRaw.html +4 -0
- package/dist/docs/hierarchy.html +1 -0
- package/dist/docs/index.html +129 -0
- package/dist/docs/interfaces/Computed.html +9 -0
- package/dist/docs/interfaces/Effect.html +8 -0
- package/dist/docs/interfaces/Ref.html +9 -0
- package/dist/docs/modules.html +1 -0
- package/dist/docs/types/Reactive.html +3 -0
- package/dist/docs/types/UnReadonly.html +3 -0
- package/dist/files/RobotoMono-Medium.woff2 +0 -0
- package/dist/files/RobotoMono-Regular.woff2 +0 -0
- package/dist/files/ic_code_black_24dp.svg +4 -0
- package/dist/files/ic_search_black_24dp.svg +4 -0
- package/dist/files/main.css +629 -0
- package/dist/files/thumbnails.svg +7 -0
- package/dist/files.json +7 -0
- package/dist/index.html +84 -0
- package/dist/index.js +733 -157
- package/dist/index.js.map +1 -1
- package/dist/index.umd.cjs +733 -157
- package/dist/index.umd.cjs.map +1 -1
- package/dist/screenshots//345/244/215/346/235/202/346/203/205/345/206/265/345/217/226/345/200/274.jpg +0 -0
- package/dist/screenshots//346/225/260/347/273/204.jpg +0 -0
- package/dist/src//345/244/215/346/235/202/346/203/205/345/206/265/345/217/226/345/200/274/index.html +70 -0
- package/dist/src//346/225/260/347/273/204/index.html +65 -0
- package/dist/tags.json +2 -0
- package/lib/Reactivity.d.ts +47 -13
- package/lib/Reactivity.d.ts.map +1 -1
- package/lib/arrayInstrumentations.d.ts +10 -0
- package/lib/arrayInstrumentations.d.ts.map +1 -1
- package/lib/baseHandlers.d.ts +3 -1
- package/lib/baseHandlers.d.ts.map +1 -1
- package/lib/batch.d.ts +17 -5
- package/lib/batch.d.ts.map +1 -1
- package/lib/collectionHandlers.d.ts +21 -0
- package/lib/collectionHandlers.d.ts.map +1 -1
- package/lib/computed.d.ts +75 -27
- package/lib/computed.d.ts.map +1 -1
- package/lib/effect.d.ts +25 -0
- package/lib/effect.d.ts.map +1 -1
- package/lib/effectScope.d.ts +129 -0
- package/lib/effectScope.d.ts.map +1 -0
- package/lib/index.d.ts +6 -5
- package/lib/index.d.ts.map +1 -1
- package/lib/property.d.ts.map +1 -1
- package/lib/reactive.d.ts +58 -17
- package/lib/reactive.d.ts.map +1 -1
- package/lib/ref.d.ts +66 -4
- package/lib/ref.d.ts.map +1 -1
- package/lib/shared/constants.d.ts +7 -7
- package/lib/shared/constants.d.ts.map +1 -1
- package/lib/shared/general.d.ts +1 -1
- package/lib/shared/general.d.ts.map +1 -1
- package/package.json +19 -17
- package/src/Reactivity.ts +57 -15
- package/src/arrayInstrumentations.ts +406 -53
- package/src/baseHandlers.ts +124 -32
- package/src/batch.ts +38 -11
- package/src/collectionHandlers.ts +207 -19
- package/src/computed.ts +92 -43
- package/src/effect.ts +38 -0
- package/src/effectScope.ts +294 -0
- package/src/index.ts +6 -5
- package/src/property.ts +6 -0
- package/src/reactive.ts +67 -20
- package/src/ref.ts +66 -4
package/dist/index.js
CHANGED
|
@@ -6,33 +6,42 @@ class Reactivity {
|
|
|
6
6
|
* 获取当前节点值。
|
|
7
7
|
*
|
|
8
8
|
* 取值时将会建立与父节点的依赖关系。
|
|
9
|
+
* 当其他响应式节点访问此值时,会自动建立依赖关系。
|
|
9
10
|
*/
|
|
10
11
|
get value() {
|
|
11
12
|
this.track();
|
|
12
13
|
return this._value;
|
|
13
14
|
}
|
|
14
15
|
/**
|
|
15
|
-
*
|
|
16
|
+
* 建立依赖关系。
|
|
16
17
|
*
|
|
17
|
-
*
|
|
18
|
+
* 当其他节点访问当前节点的值时,会调用此方法。
|
|
19
|
+
* 将当前节点与访问者(父节点)建立依赖关系。
|
|
20
|
+
*
|
|
21
|
+
* 如果当前没有活动的响应式节点,或者不应该跟踪依赖,则不会建立依赖关系。
|
|
18
22
|
*/
|
|
19
23
|
track() {
|
|
20
|
-
if (!Reactivity.activeReactivity || !_shouldTrack)
|
|
21
|
-
return;
|
|
24
|
+
if (!Reactivity.activeReactivity || !_shouldTrack) return;
|
|
22
25
|
const parent = Reactivity.activeReactivity;
|
|
23
26
|
if (parent) {
|
|
24
27
|
this._parents.set(parent, parent._version);
|
|
25
28
|
}
|
|
26
29
|
}
|
|
27
30
|
/**
|
|
28
|
-
*
|
|
31
|
+
* 触发更新。
|
|
32
|
+
*
|
|
33
|
+
* 当节点值发生变化时,会调用此方法。
|
|
34
|
+
* 通知所有依赖此节点的父节点进行更新。
|
|
29
35
|
*
|
|
30
|
-
*
|
|
36
|
+
* 更新过程:
|
|
37
|
+
* 1. 遍历所有父节点
|
|
38
|
+
* 2. 检查父节点的版本号是否匹配
|
|
39
|
+
* 3. 触发父节点的更新
|
|
40
|
+
* 4. 将当前节点添加到父节点的失效子节点集合中
|
|
31
41
|
*/
|
|
32
42
|
trigger() {
|
|
33
43
|
this._parents.forEach((version, parent) => {
|
|
34
|
-
if (parent._version !== version)
|
|
35
|
-
return;
|
|
44
|
+
if (parent._version !== version) return;
|
|
36
45
|
parent.trigger();
|
|
37
46
|
parent._children.set(this, this._value);
|
|
38
47
|
});
|
|
@@ -95,8 +104,9 @@ function computed(func) {
|
|
|
95
104
|
}
|
|
96
105
|
class ComputedReactivity extends Reactivity {
|
|
97
106
|
/**
|
|
98
|
-
*
|
|
99
|
-
*
|
|
107
|
+
* 创建计算反应式节点。
|
|
108
|
+
*
|
|
109
|
+
* @param func 计算函数,可以访问其他响应式数据,并返回计算结果
|
|
100
110
|
*/
|
|
101
111
|
constructor(func) {
|
|
102
112
|
super();
|
|
@@ -107,11 +117,12 @@ class ComputedReactivity extends Reactivity {
|
|
|
107
117
|
this._func = func;
|
|
108
118
|
}
|
|
109
119
|
/**
|
|
110
|
-
*
|
|
120
|
+
* 获取计算属性的值。
|
|
111
121
|
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
122
|
+
* 取值时会:
|
|
123
|
+
* 1. 检查是否需要重新计算
|
|
124
|
+
* 2. 建立与父节点的依赖关系
|
|
125
|
+
* 3. 返回当前值
|
|
115
126
|
*/
|
|
116
127
|
get value() {
|
|
117
128
|
this.runIfDirty();
|
|
@@ -119,11 +130,11 @@ class ComputedReactivity extends Reactivity {
|
|
|
119
130
|
return this._value;
|
|
120
131
|
}
|
|
121
132
|
/**
|
|
122
|
-
*
|
|
133
|
+
* 触发更新。
|
|
123
134
|
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
135
|
+
* 当依赖发生变化时,会调用此方法。
|
|
136
|
+
* 如果当前正在执行计算,会将更新延迟到计算完成后。
|
|
137
|
+
* 否则,立即通知所有父节点进行更新。
|
|
127
138
|
*/
|
|
128
139
|
trigger() {
|
|
129
140
|
if (Reactivity.activeReactivity === this) {
|
|
@@ -132,7 +143,14 @@ class ComputedReactivity extends Reactivity {
|
|
|
132
143
|
super.trigger();
|
|
133
144
|
}
|
|
134
145
|
/**
|
|
135
|
-
*
|
|
146
|
+
* 执行计算。
|
|
147
|
+
*
|
|
148
|
+
* 执行计算函数,更新当前值。
|
|
149
|
+
* 在计算过程中会:
|
|
150
|
+
* 1. 强制启用依赖跟踪
|
|
151
|
+
* 2. 保存并设置当前活动节点
|
|
152
|
+
* 3. 执行计算函数
|
|
153
|
+
* 4. 恢复活动节点
|
|
136
154
|
*/
|
|
137
155
|
run() {
|
|
138
156
|
forceTrack(() => {
|
|
@@ -144,9 +162,13 @@ class ComputedReactivity extends Reactivity {
|
|
|
144
162
|
});
|
|
145
163
|
}
|
|
146
164
|
/**
|
|
147
|
-
*
|
|
165
|
+
* 检查并执行计算。
|
|
166
|
+
*
|
|
167
|
+
* 检查当前节点是否需要重新计算:
|
|
168
|
+
* 1. 如果脏标记为 true,需要重新计算
|
|
169
|
+
* 2. 如果子节点发生变化,需要重新计算
|
|
148
170
|
*
|
|
149
|
-
*
|
|
171
|
+
* 重新计算后会清除脏标记。
|
|
150
172
|
*/
|
|
151
173
|
runIfDirty() {
|
|
152
174
|
this._isDirty = this._isDirty || this.isChildrenChanged();
|
|
@@ -156,17 +178,26 @@ class ComputedReactivity extends Reactivity {
|
|
|
156
178
|
}
|
|
157
179
|
}
|
|
158
180
|
/**
|
|
159
|
-
*
|
|
181
|
+
* 检查子节点是否发生变化。
|
|
182
|
+
*
|
|
183
|
+
* 遍历所有子节点,检查它们的值是否发生变化。
|
|
184
|
+
* 如果发生变化,返回 true,否则返回 false。
|
|
185
|
+
*
|
|
186
|
+
* 在检查过程中会:
|
|
187
|
+
* 1. 临时禁用依赖跟踪
|
|
188
|
+
* 2. 检查每个子节点的值
|
|
189
|
+
* 3. 如果子节点没有变化,重新建立依赖关系
|
|
190
|
+
* 4. 清空子节点集合
|
|
191
|
+
*
|
|
192
|
+
* @returns 是否有子节点发生变化
|
|
160
193
|
*/
|
|
161
194
|
isChildrenChanged() {
|
|
162
|
-
if (this._children.size === 0)
|
|
163
|
-
return false;
|
|
195
|
+
if (this._children.size === 0) return false;
|
|
164
196
|
let isChanged = false;
|
|
165
197
|
const preReactiveNode = Reactivity.activeReactivity;
|
|
166
198
|
Reactivity.activeReactivity = null;
|
|
167
199
|
this._children.forEach((value, node) => {
|
|
168
|
-
if (isChanged)
|
|
169
|
-
return;
|
|
200
|
+
if (isChanged) return;
|
|
170
201
|
if (node.value !== value) {
|
|
171
202
|
isChanged = true;
|
|
172
203
|
return;
|
|
@@ -182,52 +213,6 @@ class ComputedReactivity extends Reactivity {
|
|
|
182
213
|
return isChanged;
|
|
183
214
|
}
|
|
184
215
|
}
|
|
185
|
-
function effect(fn) {
|
|
186
|
-
return new EffectReactivity(fn);
|
|
187
|
-
}
|
|
188
|
-
const _EffectReactivity = class _EffectReactivity2 extends ComputedReactivity {
|
|
189
|
-
constructor(func) {
|
|
190
|
-
super(func);
|
|
191
|
-
this._isEnable = true;
|
|
192
|
-
this.runIfDirty();
|
|
193
|
-
}
|
|
194
|
-
pause() {
|
|
195
|
-
this._isEnable = false;
|
|
196
|
-
}
|
|
197
|
-
resume() {
|
|
198
|
-
if (this._isEnable)
|
|
199
|
-
return;
|
|
200
|
-
this._isEnable = true;
|
|
201
|
-
if (_EffectReactivity2.pausedQueueEffects.has(this)) {
|
|
202
|
-
_EffectReactivity2.pausedQueueEffects.delete(this);
|
|
203
|
-
this.trigger();
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
trigger() {
|
|
207
|
-
batchRun(() => {
|
|
208
|
-
super.trigger();
|
|
209
|
-
if (this._isEnable) {
|
|
210
|
-
batch(this, Reactivity.activeReactivity === this);
|
|
211
|
-
} else {
|
|
212
|
-
_EffectReactivity2.pausedQueueEffects.add(this);
|
|
213
|
-
}
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
/**
|
|
217
|
-
* 执行当前节点。
|
|
218
|
-
*
|
|
219
|
-
* 当暂停时将会直接执行被包装的函数。
|
|
220
|
-
*/
|
|
221
|
-
run() {
|
|
222
|
-
if (this._isEnable) {
|
|
223
|
-
super.run();
|
|
224
|
-
} else {
|
|
225
|
-
this._func(this._value);
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
};
|
|
229
|
-
_EffectReactivity.pausedQueueEffects = /* @__PURE__ */ new WeakSet();
|
|
230
|
-
let EffectReactivity = _EffectReactivity;
|
|
231
216
|
var ReactiveFlags = /* @__PURE__ */ ((ReactiveFlags2) => {
|
|
232
217
|
ReactiveFlags2["IS_REACTIVE"] = "__v_isReactive";
|
|
233
218
|
ReactiveFlags2["RAW"] = "__v_raw";
|
|
@@ -280,8 +265,7 @@ function targetTypeMap(rawType) {
|
|
|
280
265
|
}
|
|
281
266
|
}
|
|
282
267
|
function getTargetType(value) {
|
|
283
|
-
if (!Object.isExtensible(value))
|
|
284
|
-
return TargetType.INVALID;
|
|
268
|
+
if (!Object.isExtensible(value)) return TargetType.INVALID;
|
|
285
269
|
return targetTypeMap(toRawType(value));
|
|
286
270
|
}
|
|
287
271
|
const toTypeString = (value) => Object.prototype.toString.call(value);
|
|
@@ -296,10 +280,231 @@ function toRaw(observed) {
|
|
|
296
280
|
// @__NO_SIDE_EFFECTS__
|
|
297
281
|
function makeMap(str) {
|
|
298
282
|
const map = /* @__PURE__ */ Object.create(null);
|
|
299
|
-
for (const key of str.split(","))
|
|
300
|
-
map[key] = 1;
|
|
283
|
+
for (const key of str.split(",")) map[key] = 1;
|
|
301
284
|
return (val) => val in map;
|
|
302
285
|
}
|
|
286
|
+
let activeEffectScope;
|
|
287
|
+
class EffectScope {
|
|
288
|
+
/**
|
|
289
|
+
* 构造函数
|
|
290
|
+
* @param detached 是否创建分离的作用域
|
|
291
|
+
*/
|
|
292
|
+
constructor(detached = false) {
|
|
293
|
+
this.detached = detached;
|
|
294
|
+
this._active = true;
|
|
295
|
+
this._on = 0;
|
|
296
|
+
this.effects = [];
|
|
297
|
+
this.cleanups = [];
|
|
298
|
+
this._isPaused = false;
|
|
299
|
+
this.parent = activeEffectScope;
|
|
300
|
+
if (!detached && activeEffectScope) {
|
|
301
|
+
this.index = (activeEffectScope.scopes || (activeEffectScope.scopes = [])).push(
|
|
302
|
+
this
|
|
303
|
+
) - 1;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* 获取作用域是否处于活动状态
|
|
308
|
+
*/
|
|
309
|
+
get active() {
|
|
310
|
+
return this._active;
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* 暂停作用域
|
|
314
|
+
*
|
|
315
|
+
* 暂停当前作用域及其所有子作用域和效果
|
|
316
|
+
*/
|
|
317
|
+
pause() {
|
|
318
|
+
if (this._active) {
|
|
319
|
+
this._isPaused = true;
|
|
320
|
+
let i, l;
|
|
321
|
+
if (this.scopes) {
|
|
322
|
+
for (i = 0, l = this.scopes.length; i < l; i++) {
|
|
323
|
+
this.scopes[i].pause();
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
for (i = 0, l = this.effects.length; i < l; i++) {
|
|
327
|
+
this.effects[i].pause();
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* 恢复作用域
|
|
333
|
+
*
|
|
334
|
+
* 恢复当前作用域及其所有子作用域和效果
|
|
335
|
+
*/
|
|
336
|
+
resume() {
|
|
337
|
+
if (this._active) {
|
|
338
|
+
if (this._isPaused) {
|
|
339
|
+
this._isPaused = false;
|
|
340
|
+
let i, l;
|
|
341
|
+
if (this.scopes) {
|
|
342
|
+
for (i = 0, l = this.scopes.length; i < l; i++) {
|
|
343
|
+
this.scopes[i].resume();
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
for (i = 0, l = this.effects.length; i < l; i++) {
|
|
347
|
+
this.effects[i].resume();
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* 在作用域中运行函数
|
|
354
|
+
* @param fn 要运行的函数
|
|
355
|
+
* @returns 函数的返回值
|
|
356
|
+
*/
|
|
357
|
+
run(fn) {
|
|
358
|
+
if (this._active) {
|
|
359
|
+
const currentEffectScope = activeEffectScope;
|
|
360
|
+
try {
|
|
361
|
+
activeEffectScope = this;
|
|
362
|
+
return fn();
|
|
363
|
+
} finally {
|
|
364
|
+
activeEffectScope = currentEffectScope;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* 激活作用域
|
|
370
|
+
* 仅应在非分离的作用域上调用
|
|
371
|
+
* @internal
|
|
372
|
+
*/
|
|
373
|
+
on() {
|
|
374
|
+
if (++this._on === 1) {
|
|
375
|
+
this.prevScope = activeEffectScope;
|
|
376
|
+
activeEffectScope = this;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* 停用作用域
|
|
381
|
+
* 仅应在非分离的作用域上调用
|
|
382
|
+
* @internal
|
|
383
|
+
*/
|
|
384
|
+
off() {
|
|
385
|
+
if (this._on > 0 && --this._on === 0) {
|
|
386
|
+
activeEffectScope = this.prevScope;
|
|
387
|
+
this.prevScope = void 0;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* 停止作用域
|
|
392
|
+
*
|
|
393
|
+
* 停止当前作用域及其所有子作用域和效果,并执行清理函数
|
|
394
|
+
* @param fromParent 是否由父作用域调用
|
|
395
|
+
*/
|
|
396
|
+
stop(fromParent) {
|
|
397
|
+
if (this._active) {
|
|
398
|
+
this._active = false;
|
|
399
|
+
let i, l;
|
|
400
|
+
for (i = 0, l = this.effects.length; i < l; i++) {
|
|
401
|
+
this.effects[i].stop();
|
|
402
|
+
}
|
|
403
|
+
this.effects.length = 0;
|
|
404
|
+
for (i = 0, l = this.cleanups.length; i < l; i++) {
|
|
405
|
+
this.cleanups[i]();
|
|
406
|
+
}
|
|
407
|
+
this.cleanups.length = 0;
|
|
408
|
+
if (this.scopes) {
|
|
409
|
+
for (i = 0, l = this.scopes.length; i < l; i++) {
|
|
410
|
+
this.scopes[i].stop(true);
|
|
411
|
+
}
|
|
412
|
+
this.scopes.length = 0;
|
|
413
|
+
}
|
|
414
|
+
if (!this.detached && this.parent && !fromParent) {
|
|
415
|
+
const last = this.parent.scopes.pop();
|
|
416
|
+
if (last && last !== this) {
|
|
417
|
+
this.parent.scopes[this.index] = last;
|
|
418
|
+
last.index = this.index;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
this.parent = void 0;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
function effectScope(detached) {
|
|
426
|
+
return new EffectScope(detached);
|
|
427
|
+
}
|
|
428
|
+
function getCurrentScope() {
|
|
429
|
+
return activeEffectScope;
|
|
430
|
+
}
|
|
431
|
+
function onScopeDispose(fn, failSilently = false) {
|
|
432
|
+
if (activeEffectScope) {
|
|
433
|
+
activeEffectScope.cleanups.push(fn);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
function effect(fn) {
|
|
437
|
+
return new EffectReactivity(fn);
|
|
438
|
+
}
|
|
439
|
+
const _EffectReactivity = class _EffectReactivity extends ComputedReactivity {
|
|
440
|
+
constructor(func) {
|
|
441
|
+
super(func);
|
|
442
|
+
this._isEnable = true;
|
|
443
|
+
if (activeEffectScope && activeEffectScope.active) {
|
|
444
|
+
activeEffectScope.effects.push(this);
|
|
445
|
+
}
|
|
446
|
+
this.runIfDirty();
|
|
447
|
+
}
|
|
448
|
+
/**
|
|
449
|
+
* 暂停效果。
|
|
450
|
+
*
|
|
451
|
+
* 暂停后,当依赖发生变化时不会自动执行。
|
|
452
|
+
*/
|
|
453
|
+
pause() {
|
|
454
|
+
this._isEnable = false;
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* 恢复效果。
|
|
458
|
+
*
|
|
459
|
+
* 恢复后,当依赖发生变化时会自动执行。
|
|
460
|
+
*/
|
|
461
|
+
resume() {
|
|
462
|
+
if (this._isEnable) return;
|
|
463
|
+
this._isEnable = true;
|
|
464
|
+
if (_EffectReactivity.pausedQueueEffects.has(this)) {
|
|
465
|
+
_EffectReactivity.pausedQueueEffects.delete(this);
|
|
466
|
+
this.trigger();
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
470
|
+
* 停止效果。
|
|
471
|
+
*
|
|
472
|
+
* 停止后,效果将不再响应依赖的变化。
|
|
473
|
+
*/
|
|
474
|
+
stop() {
|
|
475
|
+
this._isEnable = false;
|
|
476
|
+
_EffectReactivity.pausedQueueEffects.delete(this);
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* 触发效果执行。
|
|
480
|
+
*
|
|
481
|
+
* 当依赖发生变化时,会调用此方法。
|
|
482
|
+
*/
|
|
483
|
+
trigger() {
|
|
484
|
+
batchRun(() => {
|
|
485
|
+
super.trigger();
|
|
486
|
+
if (this._isEnable) {
|
|
487
|
+
batch(this, Reactivity.activeReactivity === this);
|
|
488
|
+
} else {
|
|
489
|
+
_EffectReactivity.pausedQueueEffects.add(this);
|
|
490
|
+
}
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* 执行当前节点。
|
|
495
|
+
*
|
|
496
|
+
* 当暂停时将会直接执行被包装的函数。
|
|
497
|
+
*/
|
|
498
|
+
run() {
|
|
499
|
+
if (this._isEnable) {
|
|
500
|
+
super.run();
|
|
501
|
+
} else {
|
|
502
|
+
this._func(this._value);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
};
|
|
506
|
+
_EffectReactivity.pausedQueueEffects = /* @__PURE__ */ new WeakSet();
|
|
507
|
+
let EffectReactivity = _EffectReactivity;
|
|
303
508
|
function property(target, key) {
|
|
304
509
|
let depsMap = PropertyReactivity._targetMap.get(target);
|
|
305
510
|
if (!depsMap) {
|
|
@@ -313,19 +518,7 @@ function property(target, key) {
|
|
|
313
518
|
}
|
|
314
519
|
return dep;
|
|
315
520
|
}
|
|
316
|
-
class
|
|
317
|
-
constructor(target, key) {
|
|
318
|
-
super();
|
|
319
|
-
this._target = target;
|
|
320
|
-
this._key = key;
|
|
321
|
-
if (target instanceof Map || target instanceof WeakMap) {
|
|
322
|
-
this._value = target.get(key);
|
|
323
|
-
} else if (target instanceof Set || target instanceof WeakSet) {
|
|
324
|
-
this._value = target.has(key);
|
|
325
|
-
} else {
|
|
326
|
-
this._value = target[key];
|
|
327
|
-
}
|
|
328
|
-
}
|
|
521
|
+
const _PropertyReactivity = class _PropertyReactivity extends Reactivity {
|
|
329
522
|
/**
|
|
330
523
|
* 获取当前节点值。
|
|
331
524
|
*
|
|
@@ -341,11 +534,22 @@ class PropertyReactivity extends Reactivity {
|
|
|
341
534
|
} else if (isSymbol(this._key)) {
|
|
342
535
|
v = ~~this._value + 1;
|
|
343
536
|
}
|
|
344
|
-
if (v === this._value)
|
|
345
|
-
return;
|
|
537
|
+
if (v === this._value) return;
|
|
346
538
|
this.trigger();
|
|
347
539
|
this._value = v;
|
|
348
540
|
}
|
|
541
|
+
constructor(target, key) {
|
|
542
|
+
super();
|
|
543
|
+
this._target = target;
|
|
544
|
+
this._key = key;
|
|
545
|
+
if (target instanceof Map || target instanceof WeakMap) {
|
|
546
|
+
this._value = target.get(key);
|
|
547
|
+
} else if (target instanceof Set || target instanceof WeakSet) {
|
|
548
|
+
this._value = target.has(key);
|
|
549
|
+
} else {
|
|
550
|
+
this._value = target[key];
|
|
551
|
+
}
|
|
552
|
+
}
|
|
349
553
|
triggerIfChanged() {
|
|
350
554
|
}
|
|
351
555
|
/**
|
|
@@ -358,8 +562,7 @@ class PropertyReactivity extends Reactivity {
|
|
|
358
562
|
* @returns
|
|
359
563
|
*/
|
|
360
564
|
static track(target, type, key) {
|
|
361
|
-
if (!Reactivity.activeReactivity)
|
|
362
|
-
return;
|
|
565
|
+
if (!Reactivity.activeReactivity) return;
|
|
363
566
|
const dep = property(target, key);
|
|
364
567
|
dep.track();
|
|
365
568
|
}
|
|
@@ -375,8 +578,7 @@ class PropertyReactivity extends Reactivity {
|
|
|
375
578
|
*/
|
|
376
579
|
static trigger(target, type, key, newValue, oldValue) {
|
|
377
580
|
const depsMap = this._targetMap.get(target);
|
|
378
|
-
if (!depsMap)
|
|
379
|
-
return;
|
|
581
|
+
if (!depsMap) return;
|
|
380
582
|
const run = (dep) => {
|
|
381
583
|
if (dep) {
|
|
382
584
|
dep.value = newValue;
|
|
@@ -431,18 +633,34 @@ class PropertyReactivity extends Reactivity {
|
|
|
431
633
|
}
|
|
432
634
|
});
|
|
433
635
|
}
|
|
434
|
-
}
|
|
435
|
-
|
|
636
|
+
};
|
|
637
|
+
_PropertyReactivity._targetMap = /* @__PURE__ */ new WeakMap();
|
|
638
|
+
let PropertyReactivity = _PropertyReactivity;
|
|
436
639
|
const arrayInstrumentations = {
|
|
437
640
|
__proto__: null,
|
|
438
641
|
/**
|
|
439
|
-
*
|
|
642
|
+
* 返回一个迭代器,用于遍历数组的响应式值。
|
|
643
|
+
*
|
|
644
|
+
* 实现了以下功能:
|
|
645
|
+
* 1. 创建数组的迭代器
|
|
646
|
+
* 2. 自动将迭代的值转换为响应式
|
|
647
|
+
* 3. 自动追踪数组的访问
|
|
648
|
+
*
|
|
649
|
+
* @returns 数组的迭代器
|
|
440
650
|
*/
|
|
441
651
|
[Symbol.iterator]() {
|
|
442
652
|
return iterator(this, Symbol.iterator, toReactive);
|
|
443
653
|
},
|
|
444
654
|
/**
|
|
445
|
-
*
|
|
655
|
+
* 连接数组并返回新数组。
|
|
656
|
+
*
|
|
657
|
+
* 实现了以下功能:
|
|
658
|
+
* 1. 处理响应式数组的连接
|
|
659
|
+
* 2. 自动将参数中的数组转换为响应式
|
|
660
|
+
* 3. 保持原始值的引用
|
|
661
|
+
*
|
|
662
|
+
* @param args 要连接的数组或值
|
|
663
|
+
* @returns 连接后的新数组
|
|
446
664
|
*/
|
|
447
665
|
concat(...args) {
|
|
448
666
|
return reactiveReadArray(this).concat(
|
|
@@ -450,7 +668,14 @@ const arrayInstrumentations = {
|
|
|
450
668
|
);
|
|
451
669
|
},
|
|
452
670
|
/**
|
|
453
|
-
*
|
|
671
|
+
* 返回一个迭代器,用于遍历数组的键值对。
|
|
672
|
+
*
|
|
673
|
+
* 实现了以下功能:
|
|
674
|
+
* 1. 创建数组的键值对迭代器
|
|
675
|
+
* 2. 自动将值转换为响应式
|
|
676
|
+
* 3. 自动追踪数组的访问
|
|
677
|
+
*
|
|
678
|
+
* @returns 数组的键值对迭代器
|
|
454
679
|
*/
|
|
455
680
|
entries() {
|
|
456
681
|
return iterator(this, "entries", (value) => {
|
|
@@ -459,148 +684,357 @@ const arrayInstrumentations = {
|
|
|
459
684
|
});
|
|
460
685
|
},
|
|
461
686
|
/**
|
|
462
|
-
*
|
|
687
|
+
* 测试数组中的所有元素是否都通过了指定函数的测试。
|
|
688
|
+
*
|
|
689
|
+
* 实现了以下功能:
|
|
690
|
+
* 1. 遍历数组元素
|
|
691
|
+
* 2. 对每个元素执行测试函数
|
|
692
|
+
* 3. 自动追踪数组的访问
|
|
693
|
+
* 4. 处理响应式值的测试
|
|
694
|
+
*
|
|
695
|
+
* @param fn 测试函数
|
|
696
|
+
* @param thisArg 测试函数的 this 值
|
|
697
|
+
* @returns 如果所有元素都通过测试则返回 true,否则返回 false
|
|
463
698
|
*/
|
|
464
699
|
every(fn, thisArg) {
|
|
465
700
|
return apply(this, "every", fn, thisArg, void 0, arguments);
|
|
466
701
|
},
|
|
467
702
|
/**
|
|
468
|
-
*
|
|
703
|
+
* 创建一个新数组,包含通过指定函数测试的所有元素。
|
|
704
|
+
*
|
|
705
|
+
* 实现了以下功能:
|
|
706
|
+
* 1. 遍历数组元素
|
|
707
|
+
* 2. 对每个元素执行测试函数
|
|
708
|
+
* 3. 自动追踪数组的访问
|
|
709
|
+
* 4. 自动将结果转换为响应式
|
|
710
|
+
*
|
|
711
|
+
* @param fn 测试函数
|
|
712
|
+
* @param thisArg 测试函数的 this 值
|
|
713
|
+
* @returns 包含通过测试的元素的新数组
|
|
469
714
|
*/
|
|
470
715
|
filter(fn, thisArg) {
|
|
471
716
|
return apply(this, "filter", fn, thisArg, (v) => v.map(toReactive), arguments);
|
|
472
717
|
},
|
|
473
718
|
/**
|
|
474
|
-
*
|
|
719
|
+
* 返回数组中满足指定测试函数的第一个元素。
|
|
720
|
+
*
|
|
721
|
+
* 实现了以下功能:
|
|
722
|
+
* 1. 遍历数组元素
|
|
723
|
+
* 2. 对每个元素执行测试函数
|
|
724
|
+
* 3. 自动追踪数组的访问
|
|
725
|
+
* 4. 自动将结果转换为响应式
|
|
726
|
+
*
|
|
727
|
+
* @param fn 测试函数
|
|
728
|
+
* @param thisArg 测试函数的 this 值
|
|
729
|
+
* @returns 第一个满足测试的元素,如果没有则返回 undefined
|
|
475
730
|
*/
|
|
476
731
|
find(fn, thisArg) {
|
|
477
732
|
return apply(this, "find", fn, thisArg, toReactive, arguments);
|
|
478
733
|
},
|
|
479
734
|
/**
|
|
480
|
-
*
|
|
735
|
+
* 返回数组中满足指定测试函数的第一个元素的索引。
|
|
736
|
+
*
|
|
737
|
+
* 实现了以下功能:
|
|
738
|
+
* 1. 遍历数组元素
|
|
739
|
+
* 2. 对每个元素执行测试函数
|
|
740
|
+
* 3. 自动追踪数组的访问
|
|
741
|
+
* 4. 处理响应式值的查找
|
|
742
|
+
*
|
|
743
|
+
* @param fn 测试函数
|
|
744
|
+
* @param thisArg 测试函数的 this 值
|
|
745
|
+
* @returns 第一个满足测试的元素的索引,如果没有则返回 -1
|
|
481
746
|
*/
|
|
482
747
|
findIndex(fn, thisArg) {
|
|
483
748
|
return apply(this, "findIndex", fn, thisArg, void 0, arguments);
|
|
484
749
|
},
|
|
485
750
|
/**
|
|
486
|
-
*
|
|
751
|
+
* 返回数组中满足指定测试函数的最后一个元素。
|
|
752
|
+
*
|
|
753
|
+
* 实现了以下功能:
|
|
754
|
+
* 1. 从后向前遍历数组元素
|
|
755
|
+
* 2. 对每个元素执行测试函数
|
|
756
|
+
* 3. 自动追踪数组的访问
|
|
757
|
+
* 4. 自动将结果转换为响应式
|
|
758
|
+
*
|
|
759
|
+
* @param fn 测试函数
|
|
760
|
+
* @param thisArg 测试函数的 this 值
|
|
761
|
+
* @returns 最后一个满足测试的元素,如果没有则返回 undefined
|
|
487
762
|
*/
|
|
488
763
|
findLast(fn, thisArg) {
|
|
489
764
|
return apply(this, "findLast", fn, thisArg, toReactive, arguments);
|
|
490
765
|
},
|
|
491
766
|
/**
|
|
492
|
-
*
|
|
767
|
+
* 返回数组中满足指定测试函数的最后一个元素的索引。
|
|
768
|
+
*
|
|
769
|
+
* 实现了以下功能:
|
|
770
|
+
* 1. 从后向前遍历数组元素
|
|
771
|
+
* 2. 对每个元素执行测试函数
|
|
772
|
+
* 3. 自动追踪数组的访问
|
|
773
|
+
* 4. 处理响应式值的查找
|
|
774
|
+
*
|
|
775
|
+
* @param fn 测试函数
|
|
776
|
+
* @param thisArg 测试函数的 this 值
|
|
777
|
+
* @returns 最后一个满足测试的元素的索引,如果没有则返回 -1
|
|
493
778
|
*/
|
|
494
779
|
findLastIndex(fn, thisArg) {
|
|
495
780
|
return apply(this, "findLastIndex", fn, thisArg, void 0, arguments);
|
|
496
781
|
},
|
|
497
|
-
// flat, flatMap
|
|
782
|
+
// flat, flatMap 可以从 ARRAY_ITERATE 中受益,但实现起来不太直接
|
|
498
783
|
/**
|
|
499
|
-
*
|
|
784
|
+
* 对数组中的每个元素执行指定函数。
|
|
785
|
+
*
|
|
786
|
+
* 实现了以下功能:
|
|
787
|
+
* 1. 遍历数组元素
|
|
788
|
+
* 2. 对每个元素执行回调函数
|
|
789
|
+
* 3. 自动追踪数组的访问
|
|
790
|
+
* 4. 处理响应式值的遍历
|
|
791
|
+
*
|
|
792
|
+
* @param fn 回调函数
|
|
793
|
+
* @param thisArg 回调函数的 this 值
|
|
500
794
|
*/
|
|
501
795
|
forEach(fn, thisArg) {
|
|
502
796
|
return apply(this, "forEach", fn, thisArg, void 0, arguments);
|
|
503
797
|
},
|
|
504
798
|
/**
|
|
505
|
-
*
|
|
799
|
+
* 判断数组是否包含指定元素。
|
|
800
|
+
*
|
|
801
|
+
* 实现了以下功能:
|
|
802
|
+
* 1. 处理响应式值的查找
|
|
803
|
+
* 2. 自动追踪数组的访问
|
|
804
|
+
* 3. 处理代理对象的查找
|
|
805
|
+
*
|
|
806
|
+
* @param args 要查找的元素
|
|
807
|
+
* @returns 如果数组包含该元素则返回 true,否则返回 false
|
|
506
808
|
*/
|
|
507
809
|
includes(...args) {
|
|
508
810
|
return searchProxy(this, "includes", args);
|
|
509
811
|
},
|
|
510
812
|
/**
|
|
511
|
-
*
|
|
813
|
+
* 返回数组中指定元素第一次出现的索引。
|
|
814
|
+
*
|
|
815
|
+
* 实现了以下功能:
|
|
816
|
+
* 1. 处理响应式值的查找
|
|
817
|
+
* 2. 自动追踪数组的访问
|
|
818
|
+
* 3. 处理代理对象的查找
|
|
819
|
+
*
|
|
820
|
+
* @param args 要查找的元素
|
|
821
|
+
* @returns 元素第一次出现的索引,如果没有则返回 -1
|
|
512
822
|
*/
|
|
513
823
|
indexOf(...args) {
|
|
514
824
|
return searchProxy(this, "indexOf", args);
|
|
515
825
|
},
|
|
516
826
|
/**
|
|
517
|
-
*
|
|
827
|
+
* 将数组的所有元素连接成一个字符串。
|
|
828
|
+
*
|
|
829
|
+
* 实现了以下功能:
|
|
830
|
+
* 1. 处理响应式数组的连接
|
|
831
|
+
* 2. 自动追踪数组的访问
|
|
832
|
+
* 3. 保持原始值的引用
|
|
833
|
+
*
|
|
834
|
+
* @param separator 分隔符
|
|
835
|
+
* @returns 连接后的字符串
|
|
518
836
|
*/
|
|
519
837
|
join(separator) {
|
|
520
838
|
return reactiveReadArray(this).join(separator);
|
|
521
839
|
},
|
|
522
|
-
// keys()
|
|
840
|
+
// keys() 迭代器只读取 length,不需要优化
|
|
523
841
|
/**
|
|
524
|
-
*
|
|
842
|
+
* 返回数组中指定元素最后一次出现的索引。
|
|
843
|
+
*
|
|
844
|
+
* 实现了以下功能:
|
|
845
|
+
* 1. 处理响应式值的查找
|
|
846
|
+
* 2. 自动追踪数组的访问
|
|
847
|
+
* 3. 处理代理对象的查找
|
|
848
|
+
*
|
|
849
|
+
* @param args 要查找的元素
|
|
850
|
+
* @returns 元素最后一次出现的索引,如果没有则返回 -1
|
|
525
851
|
*/
|
|
526
852
|
lastIndexOf(...args) {
|
|
527
853
|
return searchProxy(this, "lastIndexOf", args);
|
|
528
854
|
},
|
|
529
855
|
/**
|
|
530
|
-
*
|
|
856
|
+
* 创建一个新数组,包含对原数组每个元素调用指定函数的结果。
|
|
857
|
+
*
|
|
858
|
+
* 实现了以下功能:
|
|
859
|
+
* 1. 遍历数组元素
|
|
860
|
+
* 2. 对每个元素执行映射函数
|
|
861
|
+
* 3. 自动追踪数组的访问
|
|
862
|
+
* 4. 处理响应式值的映射
|
|
863
|
+
*
|
|
864
|
+
* @param fn 映射函数
|
|
865
|
+
* @param thisArg 映射函数的 this 值
|
|
866
|
+
* @returns 包含映射结果的新数组
|
|
531
867
|
*/
|
|
532
868
|
map(fn, thisArg) {
|
|
533
869
|
return apply(this, "map", fn, thisArg, void 0, arguments);
|
|
534
870
|
},
|
|
535
871
|
/**
|
|
536
|
-
*
|
|
872
|
+
* 移除数组的最后一个元素并返回该元素。
|
|
873
|
+
*
|
|
874
|
+
* 实现了以下功能:
|
|
875
|
+
* 1. 移除最后一个元素
|
|
876
|
+
* 2. 避免跟踪长度变化
|
|
877
|
+
* 3. 处理响应式值的移除
|
|
878
|
+
*
|
|
879
|
+
* @returns 被移除的元素
|
|
537
880
|
*/
|
|
538
881
|
pop() {
|
|
539
882
|
return noTracking(this, "pop");
|
|
540
883
|
},
|
|
541
884
|
/**
|
|
542
|
-
*
|
|
885
|
+
* 向数组末尾添加一个或多个元素。
|
|
886
|
+
*
|
|
887
|
+
* 实现了以下功能:
|
|
888
|
+
* 1. 添加新元素
|
|
889
|
+
* 2. 避免跟踪长度变化
|
|
890
|
+
* 3. 处理响应式值的添加
|
|
891
|
+
*
|
|
892
|
+
* @param args 要添加的元素
|
|
893
|
+
* @returns 数组的新长度
|
|
543
894
|
*/
|
|
544
895
|
push(...args) {
|
|
545
896
|
return noTracking(this, "push", args);
|
|
546
897
|
},
|
|
547
898
|
/**
|
|
548
|
-
*
|
|
899
|
+
* 对数组中的每个元素执行累加器函数。
|
|
900
|
+
*
|
|
901
|
+
* 实现了以下功能:
|
|
902
|
+
* 1. 从左到右遍历数组元素
|
|
903
|
+
* 2. 对每个元素执行累加器函数
|
|
904
|
+
* 3. 自动追踪数组的访问
|
|
905
|
+
* 4. 处理响应式值的累加
|
|
906
|
+
*
|
|
907
|
+
* @param fn 累加器函数
|
|
908
|
+
* @param args 初始值(可选)
|
|
909
|
+
* @returns 累加的结果
|
|
549
910
|
*/
|
|
550
911
|
reduce(fn, ...args) {
|
|
551
912
|
return reduce(this, "reduce", fn, args);
|
|
552
913
|
},
|
|
553
914
|
/**
|
|
554
|
-
*
|
|
915
|
+
* 从右到左对数组中的每个元素执行累加器函数。
|
|
916
|
+
*
|
|
917
|
+
* 实现了以下功能:
|
|
918
|
+
* 1. 从右到左遍历数组元素
|
|
919
|
+
* 2. 对每个元素执行累加器函数
|
|
920
|
+
* 3. 自动追踪数组的访问
|
|
921
|
+
* 4. 处理响应式值的累加
|
|
922
|
+
*
|
|
923
|
+
* @param fn 累加器函数
|
|
924
|
+
* @param args 初始值(可选)
|
|
925
|
+
* @returns 累加的结果
|
|
555
926
|
*/
|
|
556
927
|
reduceRight(fn, ...args) {
|
|
557
928
|
return reduce(this, "reduceRight", fn, args);
|
|
558
929
|
},
|
|
559
930
|
/**
|
|
560
|
-
*
|
|
931
|
+
* 移除数组的第一个元素并返回该元素。
|
|
932
|
+
*
|
|
933
|
+
* 实现了以下功能:
|
|
934
|
+
* 1. 移除第一个元素
|
|
935
|
+
* 2. 避免跟踪长度变化
|
|
936
|
+
* 3. 处理响应式值的移除
|
|
937
|
+
*
|
|
938
|
+
* @returns 被移除的元素
|
|
561
939
|
*/
|
|
562
940
|
shift() {
|
|
563
941
|
return noTracking(this, "shift");
|
|
564
942
|
},
|
|
565
|
-
// slice
|
|
943
|
+
// slice 可以使用 ARRAY_ITERATE,但似乎也需要范围追踪
|
|
566
944
|
/**
|
|
567
|
-
*
|
|
945
|
+
* 测试数组中的某些元素是否通过了指定函数的测试。
|
|
946
|
+
*
|
|
947
|
+
* 实现了以下功能:
|
|
948
|
+
* 1. 遍历数组元素
|
|
949
|
+
* 2. 对每个元素执行测试函数
|
|
950
|
+
* 3. 自动追踪数组的访问
|
|
951
|
+
* 4. 处理响应式值的测试
|
|
952
|
+
*
|
|
953
|
+
* @param fn 测试函数
|
|
954
|
+
* @param thisArg 测试函数的 this 值
|
|
955
|
+
* @returns 如果有元素通过测试则返回 true,否则返回 false
|
|
568
956
|
*/
|
|
569
957
|
some(fn, thisArg) {
|
|
570
958
|
return apply(this, "some", fn, thisArg, void 0, arguments);
|
|
571
959
|
},
|
|
572
960
|
/**
|
|
573
|
-
*
|
|
961
|
+
* 通过删除或替换现有元素或添加新元素来修改数组。
|
|
962
|
+
*
|
|
963
|
+
* 实现了以下功能:
|
|
964
|
+
* 1. 修改数组内容
|
|
965
|
+
* 2. 避免跟踪长度变化
|
|
966
|
+
* 3. 处理响应式值的修改
|
|
967
|
+
*
|
|
968
|
+
* @param args 要删除的起始索引、要删除的元素数量和要添加的元素
|
|
969
|
+
* @returns 包含被删除元素的新数组
|
|
574
970
|
*/
|
|
575
971
|
splice(...args) {
|
|
576
972
|
return noTracking(this, "splice", args);
|
|
577
973
|
},
|
|
578
974
|
/**
|
|
579
|
-
*
|
|
975
|
+
* 返回一个新数组,包含原数组的反转副本。
|
|
976
|
+
*
|
|
977
|
+
* 实现了以下功能:
|
|
978
|
+
* 1. 创建数组的反转副本
|
|
979
|
+
* 2. 自动将结果转换为响应式
|
|
980
|
+
* 3. 保持原始值的引用
|
|
981
|
+
*
|
|
982
|
+
* @returns 反转后的新数组
|
|
580
983
|
*/
|
|
581
984
|
toReversed() {
|
|
582
985
|
return reactiveReadArray(this).toReversed();
|
|
583
986
|
},
|
|
584
987
|
/**
|
|
585
|
-
*
|
|
988
|
+
* 返回一个新数组,包含原数组的排序副本。
|
|
989
|
+
*
|
|
990
|
+
* 实现了以下功能:
|
|
991
|
+
* 1. 创建数组的排序副本
|
|
992
|
+
* 2. 自动将结果转换为响应式
|
|
993
|
+
* 3. 保持原始值的引用
|
|
994
|
+
*
|
|
995
|
+
* @param comparer 比较函数
|
|
996
|
+
* @returns 排序后的新数组
|
|
586
997
|
*/
|
|
587
998
|
toSorted(comparer) {
|
|
588
999
|
return reactiveReadArray(this).toSorted(comparer);
|
|
589
1000
|
},
|
|
590
1001
|
/**
|
|
591
|
-
*
|
|
1002
|
+
* 返回一个新数组,包含原数组的切片副本。
|
|
1003
|
+
*
|
|
1004
|
+
* 实现了以下功能:
|
|
1005
|
+
* 1. 创建数组的切片副本
|
|
1006
|
+
* 2. 自动将结果转换为响应式
|
|
1007
|
+
* 3. 保持原始值的引用
|
|
1008
|
+
*
|
|
1009
|
+
* @param args 起始索引和结束索引
|
|
1010
|
+
* @returns 切片后的新数组
|
|
592
1011
|
*/
|
|
593
1012
|
toSpliced(...args) {
|
|
594
1013
|
return reactiveReadArray(this).toSpliced(...args);
|
|
595
1014
|
},
|
|
596
1015
|
/**
|
|
597
|
-
*
|
|
1016
|
+
* 向数组开头添加一个或多个元素。
|
|
1017
|
+
*
|
|
1018
|
+
* 实现了以下功能:
|
|
1019
|
+
* 1. 添加新元素
|
|
1020
|
+
* 2. 避免跟踪长度变化
|
|
1021
|
+
* 3. 处理响应式值的添加
|
|
1022
|
+
*
|
|
1023
|
+
* @param args 要添加的元素
|
|
1024
|
+
* @returns 数组的新长度
|
|
598
1025
|
*/
|
|
599
1026
|
unshift(...args) {
|
|
600
1027
|
return noTracking(this, "unshift", args);
|
|
601
1028
|
},
|
|
602
1029
|
/**
|
|
603
|
-
*
|
|
1030
|
+
* 返回一个迭代器,用于遍历数组的值。
|
|
1031
|
+
*
|
|
1032
|
+
* 实现了以下功能:
|
|
1033
|
+
* 1. 创建数组的值迭代器
|
|
1034
|
+
* 2. 自动将迭代的值转换为响应式
|
|
1035
|
+
* 3. 自动追踪数组的访问
|
|
1036
|
+
*
|
|
1037
|
+
* @returns 数组的值迭代器
|
|
604
1038
|
*/
|
|
605
1039
|
values() {
|
|
606
1040
|
return iterator(this, "values", toReactive);
|
|
@@ -627,8 +1061,7 @@ function shallowReadArray(arr) {
|
|
|
627
1061
|
}
|
|
628
1062
|
function reactiveReadArray(array) {
|
|
629
1063
|
const raw = toRaw(array);
|
|
630
|
-
if (raw === array)
|
|
631
|
-
return raw;
|
|
1064
|
+
if (raw === array) return raw;
|
|
632
1065
|
PropertyReactivity.track(raw, TrackOpTypes.ITERATE, ARRAY_ITERATE_KEY);
|
|
633
1066
|
return raw.map(toReactive);
|
|
634
1067
|
}
|
|
@@ -683,7 +1116,7 @@ function noTracking(self, method, args = []) {
|
|
|
683
1116
|
);
|
|
684
1117
|
return res;
|
|
685
1118
|
}
|
|
686
|
-
var _a;
|
|
1119
|
+
var _a, _b;
|
|
687
1120
|
function ref(value) {
|
|
688
1121
|
if (isRef(value)) {
|
|
689
1122
|
return value;
|
|
@@ -693,22 +1126,45 @@ function ref(value) {
|
|
|
693
1126
|
function isRef(r) {
|
|
694
1127
|
return r ? r[ReactiveFlags.IS_REF] === true : false;
|
|
695
1128
|
}
|
|
696
|
-
class RefReactivity extends Reactivity {
|
|
1129
|
+
class RefReactivity extends (_b = Reactivity, _a = ReactiveFlags.IS_REF, _b) {
|
|
1130
|
+
/**
|
|
1131
|
+
* 创建引用反应式节点。
|
|
1132
|
+
*
|
|
1133
|
+
* @param value 要包装的值
|
|
1134
|
+
*/
|
|
697
1135
|
constructor(value) {
|
|
698
1136
|
super();
|
|
699
1137
|
this[_a] = true;
|
|
700
1138
|
this._rawValue = toRaw(value);
|
|
701
1139
|
this._value = toReactive(value);
|
|
702
1140
|
}
|
|
1141
|
+
/**
|
|
1142
|
+
* 获取引用的值。
|
|
1143
|
+
*
|
|
1144
|
+
* 取值时会:
|
|
1145
|
+
* 1. 建立依赖关系
|
|
1146
|
+
* 2. 返回当前值
|
|
1147
|
+
*/
|
|
703
1148
|
get value() {
|
|
704
1149
|
this.track();
|
|
705
1150
|
return this._value;
|
|
706
1151
|
}
|
|
1152
|
+
/**
|
|
1153
|
+
* 设置引用的值。
|
|
1154
|
+
*
|
|
1155
|
+
* 设置值时会:
|
|
1156
|
+
* 1. 比较新旧值是否发生变化
|
|
1157
|
+
* 2. 如果值发生变化,则:
|
|
1158
|
+
* - 触发更新通知
|
|
1159
|
+
* - 更新原始值
|
|
1160
|
+
* - 更新响应式值
|
|
1161
|
+
*
|
|
1162
|
+
* @param v 要设置的新值
|
|
1163
|
+
*/
|
|
707
1164
|
set value(v) {
|
|
708
1165
|
const oldValue = this._rawValue;
|
|
709
1166
|
const newValue = toRaw(v);
|
|
710
|
-
if (!hasChanged(oldValue, newValue))
|
|
711
|
-
return;
|
|
1167
|
+
if (!hasChanged(oldValue, newValue)) return;
|
|
712
1168
|
batchRun(() => {
|
|
713
1169
|
this.trigger();
|
|
714
1170
|
this._rawValue = newValue;
|
|
@@ -716,15 +1172,22 @@ class RefReactivity extends Reactivity {
|
|
|
716
1172
|
});
|
|
717
1173
|
}
|
|
718
1174
|
}
|
|
719
|
-
_a = ReactiveFlags.IS_REF;
|
|
720
1175
|
class BaseReactiveHandler {
|
|
721
1176
|
/**
|
|
722
1177
|
* 获取对象的属性值。
|
|
723
1178
|
*
|
|
724
|
-
*
|
|
725
|
-
*
|
|
726
|
-
*
|
|
727
|
-
*
|
|
1179
|
+
* 实现了以下功能:
|
|
1180
|
+
* 1. 响应式对象标识检查
|
|
1181
|
+
* 2. 原始对象获取
|
|
1182
|
+
* 3. 数组方法拦截
|
|
1183
|
+
* 4. 属性依赖追踪
|
|
1184
|
+
* 5. 值的自动解包
|
|
1185
|
+
* 6. 对象的自动响应式转换
|
|
1186
|
+
*
|
|
1187
|
+
* @param target 被代理的原始对象
|
|
1188
|
+
* @param key 要获取的属性名
|
|
1189
|
+
* @param receiver 代理对象本身
|
|
1190
|
+
* @returns 获取到的属性值
|
|
728
1191
|
*/
|
|
729
1192
|
get(target, key, receiver) {
|
|
730
1193
|
if (key === ReactiveFlags.IS_REACTIVE) {
|
|
@@ -764,11 +1227,18 @@ class BaseReactiveHandler {
|
|
|
764
1227
|
class MutableReactiveHandler extends BaseReactiveHandler {
|
|
765
1228
|
/**
|
|
766
1229
|
* 设置对象的属性值。
|
|
767
|
-
*
|
|
768
|
-
*
|
|
769
|
-
*
|
|
770
|
-
*
|
|
771
|
-
*
|
|
1230
|
+
*
|
|
1231
|
+
* 实现了以下功能:
|
|
1232
|
+
* 1. 值的原始化处理
|
|
1233
|
+
* 2. ref 值的特殊处理
|
|
1234
|
+
* 3. 属性变更通知
|
|
1235
|
+
* 4. 数组长度的特殊处理
|
|
1236
|
+
*
|
|
1237
|
+
* @param target 被代理的原始对象
|
|
1238
|
+
* @param key 要设置的属性名
|
|
1239
|
+
* @param value 要设置的新值
|
|
1240
|
+
* @param receiver 代理对象本身
|
|
1241
|
+
* @returns 设置是否成功
|
|
772
1242
|
*/
|
|
773
1243
|
set(target, key, value, receiver) {
|
|
774
1244
|
let oldValue = target[key];
|
|
@@ -797,9 +1267,13 @@ class MutableReactiveHandler extends BaseReactiveHandler {
|
|
|
797
1267
|
/**
|
|
798
1268
|
* 删除对象的属性。
|
|
799
1269
|
*
|
|
800
|
-
*
|
|
801
|
-
*
|
|
802
|
-
*
|
|
1270
|
+
* 实现了以下功能:
|
|
1271
|
+
* 1. 属性删除操作
|
|
1272
|
+
* 2. 删除后的变更通知
|
|
1273
|
+
*
|
|
1274
|
+
* @param target 被代理的原始对象
|
|
1275
|
+
* @param key 要删除的属性名
|
|
1276
|
+
* @returns 删除是否成功
|
|
803
1277
|
*/
|
|
804
1278
|
deleteProperty(target, key) {
|
|
805
1279
|
const hadKey = hasOwn(target, key);
|
|
@@ -810,6 +1284,17 @@ class MutableReactiveHandler extends BaseReactiveHandler {
|
|
|
810
1284
|
}
|
|
811
1285
|
return result;
|
|
812
1286
|
}
|
|
1287
|
+
/**
|
|
1288
|
+
* 检查对象是否包含某个属性。
|
|
1289
|
+
*
|
|
1290
|
+
* 实现了以下功能:
|
|
1291
|
+
* 1. 属性存在性检查
|
|
1292
|
+
* 2. 属性访问依赖追踪
|
|
1293
|
+
*
|
|
1294
|
+
* @param target 被代理的原始对象
|
|
1295
|
+
* @param key 要检查的属性名
|
|
1296
|
+
* @returns 属性是否存在
|
|
1297
|
+
*/
|
|
813
1298
|
has(target, key) {
|
|
814
1299
|
const result = Reflect.has(target, key);
|
|
815
1300
|
if (!isSymbol(key) || !builtInSymbols.has(key)) {
|
|
@@ -817,6 +1302,16 @@ class MutableReactiveHandler extends BaseReactiveHandler {
|
|
|
817
1302
|
}
|
|
818
1303
|
return result;
|
|
819
1304
|
}
|
|
1305
|
+
/**
|
|
1306
|
+
* 获取对象的所有属性名。
|
|
1307
|
+
*
|
|
1308
|
+
* 实现了以下功能:
|
|
1309
|
+
* 1. 属性遍历
|
|
1310
|
+
* 2. 遍历操作的依赖追踪
|
|
1311
|
+
*
|
|
1312
|
+
* @param target 被代理的原始对象
|
|
1313
|
+
* @returns 对象的所有属性名数组
|
|
1314
|
+
*/
|
|
820
1315
|
ownKeys(target) {
|
|
821
1316
|
PropertyReactivity.track(
|
|
822
1317
|
target,
|
|
@@ -828,8 +1323,7 @@ class MutableReactiveHandler extends BaseReactiveHandler {
|
|
|
828
1323
|
}
|
|
829
1324
|
const mutableHandlers = new MutableReactiveHandler();
|
|
830
1325
|
function hasOwnProperty(key) {
|
|
831
|
-
if (!isSymbol(key))
|
|
832
|
-
key = String(key);
|
|
1326
|
+
if (!isSymbol(key)) key = String(key);
|
|
833
1327
|
const obj = toRaw(this);
|
|
834
1328
|
PropertyReactivity.track(obj, TrackOpTypes.HAS, key);
|
|
835
1329
|
return obj.hasOwnProperty(key);
|
|
@@ -858,6 +1352,17 @@ function createInstrumentationGetter() {
|
|
|
858
1352
|
}
|
|
859
1353
|
function createInstrumentations() {
|
|
860
1354
|
const instrumentations = {
|
|
1355
|
+
/**
|
|
1356
|
+
* 获取 Map 中的值。
|
|
1357
|
+
*
|
|
1358
|
+
* 实现了以下功能:
|
|
1359
|
+
* 1. 支持原始键和响应式键的查找
|
|
1360
|
+
* 2. 自动追踪键的访问
|
|
1361
|
+
* 3. 自动将返回值转换为响应式
|
|
1362
|
+
*
|
|
1363
|
+
* @param key 要查找的键
|
|
1364
|
+
* @returns 找到的值,如果不存在则返回 undefined
|
|
1365
|
+
*/
|
|
861
1366
|
get(key) {
|
|
862
1367
|
const target = this[ReactiveFlags.RAW];
|
|
863
1368
|
const rawTarget = toRaw(target);
|
|
@@ -876,11 +1381,28 @@ function createInstrumentations() {
|
|
|
876
1381
|
target.get(key);
|
|
877
1382
|
}
|
|
878
1383
|
},
|
|
1384
|
+
/**
|
|
1385
|
+
* 获取集合的大小。
|
|
1386
|
+
*
|
|
1387
|
+
* 实现了以下功能:
|
|
1388
|
+
* 1. 追踪集合大小的访问
|
|
1389
|
+
* 2. 返回集合的实际大小
|
|
1390
|
+
*/
|
|
879
1391
|
get size() {
|
|
880
1392
|
const target = this[ReactiveFlags.RAW];
|
|
881
1393
|
PropertyReactivity.track(toRaw(target), TrackOpTypes.ITERATE, ITERATE_KEY);
|
|
882
1394
|
return Reflect.get(target, "size", target);
|
|
883
1395
|
},
|
|
1396
|
+
/**
|
|
1397
|
+
* 检查集合是否包含某个值。
|
|
1398
|
+
*
|
|
1399
|
+
* 实现了以下功能:
|
|
1400
|
+
* 1. 支持原始键和响应式键的检查
|
|
1401
|
+
* 2. 自动追踪键的检查
|
|
1402
|
+
*
|
|
1403
|
+
* @param key 要检查的键
|
|
1404
|
+
* @returns 如果集合包含该键则返回 true,否则返回 false
|
|
1405
|
+
*/
|
|
884
1406
|
has(key) {
|
|
885
1407
|
const target = this[ReactiveFlags.RAW];
|
|
886
1408
|
const rawTarget = toRaw(target);
|
|
@@ -891,6 +1413,17 @@ function createInstrumentations() {
|
|
|
891
1413
|
PropertyReactivity.track(rawTarget, TrackOpTypes.HAS, rawKey);
|
|
892
1414
|
return key === rawKey ? target.has(key) : target.has(key) || target.has(rawKey);
|
|
893
1415
|
},
|
|
1416
|
+
/**
|
|
1417
|
+
* 遍历集合中的所有元素。
|
|
1418
|
+
*
|
|
1419
|
+
* 实现了以下功能:
|
|
1420
|
+
* 1. 追踪集合的遍历操作
|
|
1421
|
+
* 2. 自动将遍历的值转换为响应式
|
|
1422
|
+
* 3. 保持回调函数的 this 上下文
|
|
1423
|
+
*
|
|
1424
|
+
* @param callback 遍历回调函数
|
|
1425
|
+
* @param thisArg 回调函数的 this 值
|
|
1426
|
+
*/
|
|
894
1427
|
forEach(callback, thisArg) {
|
|
895
1428
|
const observed = this;
|
|
896
1429
|
const target = observed[ReactiveFlags.RAW];
|
|
@@ -899,13 +1432,24 @@ function createInstrumentations() {
|
|
|
899
1432
|
PropertyReactivity.track(rawTarget, TrackOpTypes.ITERATE, ITERATE_KEY);
|
|
900
1433
|
return target.forEach(
|
|
901
1434
|
(value, key) => (
|
|
902
|
-
//
|
|
903
|
-
// 1.
|
|
904
|
-
// 2.
|
|
1435
|
+
// 重要:确保回调函数
|
|
1436
|
+
// 1. 使用响应式 map 作为 this 和第三个参数
|
|
1437
|
+
// 2. 接收到的值应该是相应的响应式/只读版本
|
|
905
1438
|
callback.call(thisArg, wrap(value), wrap(key), observed)
|
|
906
1439
|
)
|
|
907
1440
|
);
|
|
908
1441
|
},
|
|
1442
|
+
/**
|
|
1443
|
+
* 向 Set 中添加值。
|
|
1444
|
+
*
|
|
1445
|
+
* 实现了以下功能:
|
|
1446
|
+
* 1. 自动将值转换为原始值
|
|
1447
|
+
* 2. 避免重复添加
|
|
1448
|
+
* 3. 触发添加操作的通知
|
|
1449
|
+
*
|
|
1450
|
+
* @param value 要添加的值
|
|
1451
|
+
* @returns 集合本身,支持链式调用
|
|
1452
|
+
*/
|
|
909
1453
|
add(value) {
|
|
910
1454
|
value = toRaw(value);
|
|
911
1455
|
const target = toRaw(this);
|
|
@@ -917,6 +1461,18 @@ function createInstrumentations() {
|
|
|
917
1461
|
}
|
|
918
1462
|
return this;
|
|
919
1463
|
},
|
|
1464
|
+
/**
|
|
1465
|
+
* 设置 Map 中的值。
|
|
1466
|
+
*
|
|
1467
|
+
* 实现了以下功能:
|
|
1468
|
+
* 1. 自动将值转换为原始值
|
|
1469
|
+
* 2. 支持原始键和响应式键的设置
|
|
1470
|
+
* 3. 触发添加或修改操作的通知
|
|
1471
|
+
*
|
|
1472
|
+
* @param key 要设置的键
|
|
1473
|
+
* @param value 要设置的值
|
|
1474
|
+
* @returns 集合本身,支持链式调用
|
|
1475
|
+
*/
|
|
920
1476
|
set(key, value) {
|
|
921
1477
|
value = toRaw(value);
|
|
922
1478
|
const target = toRaw(this);
|
|
@@ -935,6 +1491,16 @@ function createInstrumentations() {
|
|
|
935
1491
|
}
|
|
936
1492
|
return this;
|
|
937
1493
|
},
|
|
1494
|
+
/**
|
|
1495
|
+
* 从集合中删除值。
|
|
1496
|
+
*
|
|
1497
|
+
* 实现了以下功能:
|
|
1498
|
+
* 1. 支持原始键和响应式键的删除
|
|
1499
|
+
* 2. 触发删除操作的通知
|
|
1500
|
+
*
|
|
1501
|
+
* @param key 要删除的键
|
|
1502
|
+
* @returns 如果删除成功则返回 true,否则返回 false
|
|
1503
|
+
*/
|
|
938
1504
|
delete(key) {
|
|
939
1505
|
const target = toRaw(this);
|
|
940
1506
|
const { has, get } = getProto(target);
|
|
@@ -950,6 +1516,16 @@ function createInstrumentations() {
|
|
|
950
1516
|
}
|
|
951
1517
|
return result;
|
|
952
1518
|
},
|
|
1519
|
+
/**
|
|
1520
|
+
* 清空集合。
|
|
1521
|
+
*
|
|
1522
|
+
* 实现了以下功能:
|
|
1523
|
+
* 1. 清空集合中的所有元素
|
|
1524
|
+
* 2. 触发清空操作的通知
|
|
1525
|
+
* 3. 在开发模式下保存旧值用于调试
|
|
1526
|
+
*
|
|
1527
|
+
* @returns 如果清空成功则返回 true,否则返回 false
|
|
1528
|
+
*/
|
|
953
1529
|
clear() {
|
|
954
1530
|
const target = toRaw(this);
|
|
955
1531
|
const hadItems = target.size !== 0;
|
|
@@ -993,7 +1569,7 @@ function createIterableMethod(method) {
|
|
|
993
1569
|
isKeyOnly ? MAP_KEY_ITERATE_KEY : ITERATE_KEY
|
|
994
1570
|
);
|
|
995
1571
|
return {
|
|
996
|
-
//
|
|
1572
|
+
// 迭代器协议
|
|
997
1573
|
next() {
|
|
998
1574
|
const { value, done } = innerIterator.next();
|
|
999
1575
|
return done ? { value, done } : {
|
|
@@ -1001,7 +1577,7 @@ function createIterableMethod(method) {
|
|
|
1001
1577
|
done
|
|
1002
1578
|
};
|
|
1003
1579
|
},
|
|
1004
|
-
//
|
|
1580
|
+
// 可迭代协议
|
|
1005
1581
|
[Symbol.iterator]() {
|
|
1006
1582
|
return this;
|
|
1007
1583
|
}
|
|
@@ -1045,18 +1621,18 @@ function isProxy(value) {
|
|
|
1045
1621
|
return value ? !!value[ReactiveFlags.RAW] : false;
|
|
1046
1622
|
}
|
|
1047
1623
|
export {
|
|
1048
|
-
|
|
1049
|
-
Reactivity as Dep,
|
|
1050
|
-
EffectReactivity as EffectDep,
|
|
1051
|
-
RefReactivity,
|
|
1624
|
+
EffectScope,
|
|
1052
1625
|
batchRun,
|
|
1053
1626
|
computed,
|
|
1054
1627
|
effect,
|
|
1628
|
+
effectScope,
|
|
1055
1629
|
forceTrack,
|
|
1630
|
+
getCurrentScope,
|
|
1056
1631
|
isProxy,
|
|
1057
1632
|
isReactive,
|
|
1058
1633
|
isRef,
|
|
1059
1634
|
noTrack,
|
|
1635
|
+
onScopeDispose,
|
|
1060
1636
|
reactive,
|
|
1061
1637
|
ref,
|
|
1062
1638
|
toRaw
|