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