@feng3d/reactivity 1.0.7 → 1.0.8
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/LICENSE +21 -21
- package/README.md +158 -158
- package/dist/index.js +89 -0
- package/dist/index.js.map +1 -1
- package/dist/index.umd.cjs +91 -2
- package/dist/index.umd.cjs.map +1 -1
- package/lib/ReactiveObject.d.ts +101 -0
- package/lib/ReactiveObject.d.ts.map +1 -0
- package/lib/batch.d.ts.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/package.json +69 -69
- package/src/ReactiveObject.ts +131 -0
- package/src/Reactivity.ts +168 -168
- package/src/arrayInstrumentations.ts +801 -801
- package/src/baseHandlers.ts +312 -312
- package/src/batch.ts +134 -118
- package/src/collectionHandlers.ts +486 -486
- package/src/computed.ts +253 -253
- package/src/effect.ts +146 -146
- package/src/effectScope.ts +294 -294
- package/src/index.ts +10 -9
- package/src/property.ts +231 -231
- package/src/reactive.ts +186 -186
- package/src/ref.ts +150 -150
- package/src/shared/constants.ts +41 -41
- package/src/shared/general.ts +109 -109
- package/tsconfig.json +19 -19
- 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 +0 -629
- package/dist/assets/index.html-Dyp3udP2.js +0 -200
- package/dist/assets/modulepreload-polyfill-DaKOjhqt.js +0 -37
- package/dist/assets/package-DuJynByc.js +0 -2539
- 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 +0 -59
- package/dist/assets/src//346/225/260/347/273/204/index.html-CHK6WEhd.js +0 -43
- package/dist/docs/.nojekyll +0 -1
- package/dist/docs/assets/hierarchy.js +0 -1
- package/dist/docs/assets/highlight.css +0 -92
- package/dist/docs/assets/icons.js +0 -18
- package/dist/docs/assets/icons.svg +0 -1
- package/dist/docs/assets/main.js +0 -60
- package/dist/docs/assets/navigation.js +0 -1
- package/dist/docs/assets/search.js +0 -1
- package/dist/docs/assets/style.css +0 -1640
- package/dist/docs/classes/EffectScope.html +0 -40
- package/dist/docs/functions/batchRun.html +0 -15
- package/dist/docs/functions/computed.html +0 -5
- package/dist/docs/functions/effect.html +0 -11
- package/dist/docs/functions/effectScope.html +0 -5
- package/dist/docs/functions/forceTrack.html +0 -6
- package/dist/docs/functions/getCurrentScope.html +0 -4
- package/dist/docs/functions/isProxy.html +0 -5
- package/dist/docs/functions/isReactive.html +0 -5
- package/dist/docs/functions/isRef.html +0 -5
- package/dist/docs/functions/noTrack.html +0 -6
- package/dist/docs/functions/onScopeDispose.html +0 -6
- package/dist/docs/functions/reactive.html +0 -19
- package/dist/docs/functions/ref.html +0 -13
- package/dist/docs/functions/toRaw.html +0 -4
- package/dist/docs/hierarchy.html +0 -1
- package/dist/docs/index.html +0 -129
- package/dist/docs/interfaces/Computed.html +0 -9
- package/dist/docs/interfaces/Effect.html +0 -8
- package/dist/docs/interfaces/Ref.html +0 -9
- package/dist/docs/modules.html +0 -1
- package/dist/docs/types/Reactive.html +0 -3
- package/dist/docs/types/UnReadonly.html +0 -3
- package/dist/files/RobotoMono-Medium.woff2 +0 -0
- package/dist/files/RobotoMono-Regular.woff2 +0 -0
- package/dist/files/ic_code_black_24dp.svg +0 -4
- package/dist/files/ic_search_black_24dp.svg +0 -4
- package/dist/files/main.css +0 -629
- package/dist/files/thumbnails.svg +0 -7
- package/dist/files.json +0 -7
- package/dist/index.html +0 -84
- 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 +0 -70
- package/dist/src//346/225/260/347/273/204/index.html +0 -65
- package/dist/tags.json +0 -2
package/src/computed.ts
CHANGED
|
@@ -1,253 +1,253 @@
|
|
|
1
|
-
import { batch } from './batch';
|
|
2
|
-
import { Reactivity, forceTrack } from './Reactivity';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* 创建计算反应式对象。
|
|
6
|
-
*
|
|
7
|
-
* 计算属性会缓存计算结果,只有当依赖发生变化时才会重新计算。
|
|
8
|
-
*
|
|
9
|
-
* @param func 计算函数,可以访问其他响应式数据,并返回计算结果
|
|
10
|
-
* @returns 包含 value 属性的计算属性对象
|
|
11
|
-
*/
|
|
12
|
-
export function computed<T>(func: (oldValue?: T) => T): Computed<T>
|
|
13
|
-
{
|
|
14
|
-
return new ComputedReactivity(func) as any;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* 计算属性接口。
|
|
19
|
-
*
|
|
20
|
-
* 定义了计算属性的基本结构:
|
|
21
|
-
* 1. value: 计算属性的当前值
|
|
22
|
-
* 2. ComputedSymbol: 用于标识这是一个计算属性
|
|
23
|
-
*/
|
|
24
|
-
export interface Computed<T = any>
|
|
25
|
-
{
|
|
26
|
-
readonly value: T
|
|
27
|
-
[ComputedSymbol]: true
|
|
28
|
-
}
|
|
29
|
-
declare const ComputedSymbol: unique symbol;
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* 计算反应式节点接口。
|
|
33
|
-
*
|
|
34
|
-
* 继承自 Computed 接口,表示这是一个计算反应式节点。
|
|
35
|
-
*/
|
|
36
|
-
export interface ComputedReactivity<T = any> extends Computed<T> { }
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* 计算反应式节点类。
|
|
40
|
-
*
|
|
41
|
-
* 当使用 computed 函数时,会创建一个 ComputedReactivity 对象。
|
|
42
|
-
* 实现了计算属性的核心功能:
|
|
43
|
-
* 1. 缓存计算结果
|
|
44
|
-
* 2. 按需重新计算
|
|
45
|
-
* 3. 依赖追踪
|
|
46
|
-
* 4. 变更通知
|
|
47
|
-
*/
|
|
48
|
-
export class ComputedReactivity<T = any> extends Reactivity<T>
|
|
49
|
-
{
|
|
50
|
-
/**
|
|
51
|
-
* 标识这是一个 ref 对象。
|
|
52
|
-
*
|
|
53
|
-
* @internal
|
|
54
|
-
*/
|
|
55
|
-
readonly __v_isRef = true;
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* 计算函数。
|
|
59
|
-
*
|
|
60
|
-
* 用于计算属性值的函数,可以访问其他响应式数据。
|
|
61
|
-
* 当依赖发生变化时,会重新执行此函数。
|
|
62
|
-
*/
|
|
63
|
-
protected _func: (oldValue?: T) => T;
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* 失效子节点集合。
|
|
67
|
-
*
|
|
68
|
-
* 记录所有依赖此计算属性的子节点。
|
|
69
|
-
* 当计算属性重新计算时,会通知这些子节点。
|
|
70
|
-
*
|
|
71
|
-
* @private
|
|
72
|
-
*/
|
|
73
|
-
_children = new Map<Reactivity, any>();
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* 脏标记。
|
|
77
|
-
*
|
|
78
|
-
* 表示计算属性是否需要重新计算。
|
|
79
|
-
* 当依赖发生变化时,会设置此标记。
|
|
80
|
-
* 重新计算后会清除此标记。
|
|
81
|
-
*
|
|
82
|
-
* @private
|
|
83
|
-
*/
|
|
84
|
-
_isDirty = true;
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* 版本号。
|
|
88
|
-
*
|
|
89
|
-
* 每次重新计算后自动递增。
|
|
90
|
-
* 用于判断子节点中的父节点引用是否过期。
|
|
91
|
-
* 当子节点发现父节点的版本号不匹配时,会重新建立依赖关系。
|
|
92
|
-
*
|
|
93
|
-
* @private
|
|
94
|
-
*/
|
|
95
|
-
_version = -1;
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* 获取计算属性的值。
|
|
99
|
-
*
|
|
100
|
-
* 取值时会:
|
|
101
|
-
* 1. 检查是否需要重新计算
|
|
102
|
-
* 2. 建立与父节点的依赖关系
|
|
103
|
-
* 3. 返回当前值
|
|
104
|
-
*/
|
|
105
|
-
get value(): T
|
|
106
|
-
{
|
|
107
|
-
this.runIfDirty();
|
|
108
|
-
this.track();
|
|
109
|
-
|
|
110
|
-
return this._value;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* 创建计算反应式节点。
|
|
115
|
-
*
|
|
116
|
-
* @param func 计算函数,可以访问其他响应式数据,并返回计算结果
|
|
117
|
-
*/
|
|
118
|
-
constructor(func: (oldValue?: T) => T)
|
|
119
|
-
{
|
|
120
|
-
super();
|
|
121
|
-
this._func = func;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* 触发更新。
|
|
126
|
-
*
|
|
127
|
-
* 当依赖发生变化时,会调用此方法。
|
|
128
|
-
* 如果当前正在执行计算,会将更新延迟到计算完成后。
|
|
129
|
-
* 否则,立即通知所有父节点进行更新。
|
|
130
|
-
*/
|
|
131
|
-
trigger(): void
|
|
132
|
-
{
|
|
133
|
-
// 正在运行时被触发,需要在运行结束后修复父子节点关系
|
|
134
|
-
if (Reactivity.activeReactivity === this)
|
|
135
|
-
{
|
|
136
|
-
batch(this, Reactivity.activeReactivity === this);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
super.trigger();
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* 执行计算。
|
|
144
|
-
*
|
|
145
|
-
* 执行计算函数,更新当前值。
|
|
146
|
-
* 在计算过程中会:
|
|
147
|
-
* 1. 强制启用依赖跟踪
|
|
148
|
-
* 2. 保存并设置当前活动节点
|
|
149
|
-
* 3. 执行计算函数
|
|
150
|
-
* 4. 恢复活动节点
|
|
151
|
-
*/
|
|
152
|
-
run()
|
|
153
|
-
{
|
|
154
|
-
// 不受嵌套的 effect 影响
|
|
155
|
-
forceTrack(() =>
|
|
156
|
-
{
|
|
157
|
-
// 保存当前节点作为父节点
|
|
158
|
-
const parentReactiveNode = Reactivity.activeReactivity;
|
|
159
|
-
|
|
160
|
-
// 设置当前节点为活跃节点
|
|
161
|
-
Reactivity.activeReactivity = this as any;
|
|
162
|
-
|
|
163
|
-
this._version++;
|
|
164
|
-
this._value = this._func(this._value);
|
|
165
|
-
|
|
166
|
-
// 执行完毕后恢复父节点
|
|
167
|
-
Reactivity.activeReactivity = parentReactiveNode;
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* 检查并执行计算。
|
|
173
|
-
*
|
|
174
|
-
* 检查当前节点是否需要重新计算:
|
|
175
|
-
* 1. 如果脏标记为 true,需要重新计算
|
|
176
|
-
* 2. 如果子节点发生变化,需要重新计算
|
|
177
|
-
*
|
|
178
|
-
* 重新计算后会清除脏标记。
|
|
179
|
-
*/
|
|
180
|
-
runIfDirty()
|
|
181
|
-
{
|
|
182
|
-
// 检查是否存在失效子节点字典
|
|
183
|
-
this._isDirty = this._isDirty || this.isChildrenChanged();
|
|
184
|
-
|
|
185
|
-
// 标记为脏的情况下,执行计算
|
|
186
|
-
if (this._isDirty)
|
|
187
|
-
{
|
|
188
|
-
// 立即去除脏标记,避免循环多重计算
|
|
189
|
-
this._isDirty = false;
|
|
190
|
-
|
|
191
|
-
// 执行计算
|
|
192
|
-
this.run();
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
/**
|
|
197
|
-
* 检查子节点是否发生变化。
|
|
198
|
-
*
|
|
199
|
-
* 遍历所有子节点,检查它们的值是否发生变化。
|
|
200
|
-
* 如果发生变化,返回 true,否则返回 false。
|
|
201
|
-
*
|
|
202
|
-
* 在检查过程中会:
|
|
203
|
-
* 1. 临时禁用依赖跟踪
|
|
204
|
-
* 2. 检查每个子节点的值
|
|
205
|
-
* 3. 如果子节点没有变化,重新建立依赖关系
|
|
206
|
-
* 4. 清空子节点集合
|
|
207
|
-
*
|
|
208
|
-
* @returns 是否有子节点发生变化
|
|
209
|
-
*/
|
|
210
|
-
protected isChildrenChanged()
|
|
211
|
-
{
|
|
212
|
-
if (this._children.size === 0) return false;
|
|
213
|
-
|
|
214
|
-
// 检查是否存在子节点发生变化
|
|
215
|
-
let isChanged = false;
|
|
216
|
-
|
|
217
|
-
// 避免在检查过程建立依赖关系
|
|
218
|
-
const preReactiveNode = Reactivity.activeReactivity;
|
|
219
|
-
|
|
220
|
-
Reactivity.activeReactivity = null;
|
|
221
|
-
|
|
222
|
-
// 检查子节点是否发生变化
|
|
223
|
-
this._children.forEach((value, node) =>
|
|
224
|
-
{
|
|
225
|
-
if (isChanged) return;
|
|
226
|
-
if (node.value !== value)
|
|
227
|
-
{
|
|
228
|
-
// 子节点变化,需要重新计算
|
|
229
|
-
isChanged = true;
|
|
230
|
-
|
|
231
|
-
return;
|
|
232
|
-
}
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
// 恢复父节点
|
|
236
|
-
Reactivity.activeReactivity = preReactiveNode;
|
|
237
|
-
|
|
238
|
-
if (!isChanged)
|
|
239
|
-
{
|
|
240
|
-
// 修复与子节点关系
|
|
241
|
-
this._children.forEach((version, node) =>
|
|
242
|
-
{
|
|
243
|
-
node._parents.set(this, this._version);
|
|
244
|
-
});
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
// 清空子节点
|
|
248
|
-
this._children.clear();
|
|
249
|
-
|
|
250
|
-
return isChanged;
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
|
|
1
|
+
import { batch } from './batch';
|
|
2
|
+
import { Reactivity, forceTrack } from './Reactivity';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 创建计算反应式对象。
|
|
6
|
+
*
|
|
7
|
+
* 计算属性会缓存计算结果,只有当依赖发生变化时才会重新计算。
|
|
8
|
+
*
|
|
9
|
+
* @param func 计算函数,可以访问其他响应式数据,并返回计算结果
|
|
10
|
+
* @returns 包含 value 属性的计算属性对象
|
|
11
|
+
*/
|
|
12
|
+
export function computed<T>(func: (oldValue?: T) => T): Computed<T>
|
|
13
|
+
{
|
|
14
|
+
return new ComputedReactivity(func) as any;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* 计算属性接口。
|
|
19
|
+
*
|
|
20
|
+
* 定义了计算属性的基本结构:
|
|
21
|
+
* 1. value: 计算属性的当前值
|
|
22
|
+
* 2. ComputedSymbol: 用于标识这是一个计算属性
|
|
23
|
+
*/
|
|
24
|
+
export interface Computed<T = any>
|
|
25
|
+
{
|
|
26
|
+
readonly value: T
|
|
27
|
+
[ComputedSymbol]: true
|
|
28
|
+
}
|
|
29
|
+
declare const ComputedSymbol: unique symbol;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* 计算反应式节点接口。
|
|
33
|
+
*
|
|
34
|
+
* 继承自 Computed 接口,表示这是一个计算反应式节点。
|
|
35
|
+
*/
|
|
36
|
+
export interface ComputedReactivity<T = any> extends Computed<T> { }
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* 计算反应式节点类。
|
|
40
|
+
*
|
|
41
|
+
* 当使用 computed 函数时,会创建一个 ComputedReactivity 对象。
|
|
42
|
+
* 实现了计算属性的核心功能:
|
|
43
|
+
* 1. 缓存计算结果
|
|
44
|
+
* 2. 按需重新计算
|
|
45
|
+
* 3. 依赖追踪
|
|
46
|
+
* 4. 变更通知
|
|
47
|
+
*/
|
|
48
|
+
export class ComputedReactivity<T = any> extends Reactivity<T>
|
|
49
|
+
{
|
|
50
|
+
/**
|
|
51
|
+
* 标识这是一个 ref 对象。
|
|
52
|
+
*
|
|
53
|
+
* @internal
|
|
54
|
+
*/
|
|
55
|
+
readonly __v_isRef = true;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* 计算函数。
|
|
59
|
+
*
|
|
60
|
+
* 用于计算属性值的函数,可以访问其他响应式数据。
|
|
61
|
+
* 当依赖发生变化时,会重新执行此函数。
|
|
62
|
+
*/
|
|
63
|
+
protected _func: (oldValue?: T) => T;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* 失效子节点集合。
|
|
67
|
+
*
|
|
68
|
+
* 记录所有依赖此计算属性的子节点。
|
|
69
|
+
* 当计算属性重新计算时,会通知这些子节点。
|
|
70
|
+
*
|
|
71
|
+
* @private
|
|
72
|
+
*/
|
|
73
|
+
_children = new Map<Reactivity, any>();
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* 脏标记。
|
|
77
|
+
*
|
|
78
|
+
* 表示计算属性是否需要重新计算。
|
|
79
|
+
* 当依赖发生变化时,会设置此标记。
|
|
80
|
+
* 重新计算后会清除此标记。
|
|
81
|
+
*
|
|
82
|
+
* @private
|
|
83
|
+
*/
|
|
84
|
+
_isDirty = true;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* 版本号。
|
|
88
|
+
*
|
|
89
|
+
* 每次重新计算后自动递增。
|
|
90
|
+
* 用于判断子节点中的父节点引用是否过期。
|
|
91
|
+
* 当子节点发现父节点的版本号不匹配时,会重新建立依赖关系。
|
|
92
|
+
*
|
|
93
|
+
* @private
|
|
94
|
+
*/
|
|
95
|
+
_version = -1;
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* 获取计算属性的值。
|
|
99
|
+
*
|
|
100
|
+
* 取值时会:
|
|
101
|
+
* 1. 检查是否需要重新计算
|
|
102
|
+
* 2. 建立与父节点的依赖关系
|
|
103
|
+
* 3. 返回当前值
|
|
104
|
+
*/
|
|
105
|
+
get value(): T
|
|
106
|
+
{
|
|
107
|
+
this.runIfDirty();
|
|
108
|
+
this.track();
|
|
109
|
+
|
|
110
|
+
return this._value;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* 创建计算反应式节点。
|
|
115
|
+
*
|
|
116
|
+
* @param func 计算函数,可以访问其他响应式数据,并返回计算结果
|
|
117
|
+
*/
|
|
118
|
+
constructor(func: (oldValue?: T) => T)
|
|
119
|
+
{
|
|
120
|
+
super();
|
|
121
|
+
this._func = func;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* 触发更新。
|
|
126
|
+
*
|
|
127
|
+
* 当依赖发生变化时,会调用此方法。
|
|
128
|
+
* 如果当前正在执行计算,会将更新延迟到计算完成后。
|
|
129
|
+
* 否则,立即通知所有父节点进行更新。
|
|
130
|
+
*/
|
|
131
|
+
trigger(): void
|
|
132
|
+
{
|
|
133
|
+
// 正在运行时被触发,需要在运行结束后修复父子节点关系
|
|
134
|
+
if (Reactivity.activeReactivity === this)
|
|
135
|
+
{
|
|
136
|
+
batch(this, Reactivity.activeReactivity === this);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
super.trigger();
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* 执行计算。
|
|
144
|
+
*
|
|
145
|
+
* 执行计算函数,更新当前值。
|
|
146
|
+
* 在计算过程中会:
|
|
147
|
+
* 1. 强制启用依赖跟踪
|
|
148
|
+
* 2. 保存并设置当前活动节点
|
|
149
|
+
* 3. 执行计算函数
|
|
150
|
+
* 4. 恢复活动节点
|
|
151
|
+
*/
|
|
152
|
+
run()
|
|
153
|
+
{
|
|
154
|
+
// 不受嵌套的 effect 影响
|
|
155
|
+
forceTrack(() =>
|
|
156
|
+
{
|
|
157
|
+
// 保存当前节点作为父节点
|
|
158
|
+
const parentReactiveNode = Reactivity.activeReactivity;
|
|
159
|
+
|
|
160
|
+
// 设置当前节点为活跃节点
|
|
161
|
+
Reactivity.activeReactivity = this as any;
|
|
162
|
+
|
|
163
|
+
this._version++;
|
|
164
|
+
this._value = this._func(this._value);
|
|
165
|
+
|
|
166
|
+
// 执行完毕后恢复父节点
|
|
167
|
+
Reactivity.activeReactivity = parentReactiveNode;
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* 检查并执行计算。
|
|
173
|
+
*
|
|
174
|
+
* 检查当前节点是否需要重新计算:
|
|
175
|
+
* 1. 如果脏标记为 true,需要重新计算
|
|
176
|
+
* 2. 如果子节点发生变化,需要重新计算
|
|
177
|
+
*
|
|
178
|
+
* 重新计算后会清除脏标记。
|
|
179
|
+
*/
|
|
180
|
+
runIfDirty()
|
|
181
|
+
{
|
|
182
|
+
// 检查是否存在失效子节点字典
|
|
183
|
+
this._isDirty = this._isDirty || this.isChildrenChanged();
|
|
184
|
+
|
|
185
|
+
// 标记为脏的情况下,执行计算
|
|
186
|
+
if (this._isDirty)
|
|
187
|
+
{
|
|
188
|
+
// 立即去除脏标记,避免循环多重计算
|
|
189
|
+
this._isDirty = false;
|
|
190
|
+
|
|
191
|
+
// 执行计算
|
|
192
|
+
this.run();
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* 检查子节点是否发生变化。
|
|
198
|
+
*
|
|
199
|
+
* 遍历所有子节点,检查它们的值是否发生变化。
|
|
200
|
+
* 如果发生变化,返回 true,否则返回 false。
|
|
201
|
+
*
|
|
202
|
+
* 在检查过程中会:
|
|
203
|
+
* 1. 临时禁用依赖跟踪
|
|
204
|
+
* 2. 检查每个子节点的值
|
|
205
|
+
* 3. 如果子节点没有变化,重新建立依赖关系
|
|
206
|
+
* 4. 清空子节点集合
|
|
207
|
+
*
|
|
208
|
+
* @returns 是否有子节点发生变化
|
|
209
|
+
*/
|
|
210
|
+
protected isChildrenChanged()
|
|
211
|
+
{
|
|
212
|
+
if (this._children.size === 0) return false;
|
|
213
|
+
|
|
214
|
+
// 检查是否存在子节点发生变化
|
|
215
|
+
let isChanged = false;
|
|
216
|
+
|
|
217
|
+
// 避免在检查过程建立依赖关系
|
|
218
|
+
const preReactiveNode = Reactivity.activeReactivity;
|
|
219
|
+
|
|
220
|
+
Reactivity.activeReactivity = null;
|
|
221
|
+
|
|
222
|
+
// 检查子节点是否发生变化
|
|
223
|
+
this._children.forEach((value, node) =>
|
|
224
|
+
{
|
|
225
|
+
if (isChanged) return;
|
|
226
|
+
if (node.value !== value)
|
|
227
|
+
{
|
|
228
|
+
// 子节点变化,需要重新计算
|
|
229
|
+
isChanged = true;
|
|
230
|
+
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
// 恢复父节点
|
|
236
|
+
Reactivity.activeReactivity = preReactiveNode;
|
|
237
|
+
|
|
238
|
+
if (!isChanged)
|
|
239
|
+
{
|
|
240
|
+
// 修复与子节点关系
|
|
241
|
+
this._children.forEach((version, node) =>
|
|
242
|
+
{
|
|
243
|
+
node._parents.set(this, this._version);
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// 清空子节点
|
|
248
|
+
this._children.clear();
|
|
249
|
+
|
|
250
|
+
return isChanged;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|