@feng3d/reactivity 1.0.6 → 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 -3
- package/dist/index.js.map +1 -1
- package/dist/index.umd.cjs +91 -5
- 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 +5 -4
- package/lib/index.d.ts.map +1 -1
- package/package.json +69 -72
- 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-9zMEdmDL.js +0 -2540
- 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 +0 -59
- package/dist/assets/src//346/225/260/347/273/204/index.html-CaZ_5kCZ.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/ComputedReactivity.html +0 -72
- package/dist/docs/classes/EffectReactivity.html +0 -62
- package/dist/docs/classes/EffectScope.html +0 -40
- package/dist/docs/classes/Reactivity.html +0 -35
- package/dist/docs/classes/RefReactivity.html +0 -57
- 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/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2019 feng
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2019 feng
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,159 +1,159 @@
|
|
|
1
|
-
# @feng3d/reactivity
|
|
2
|
-
|
|
3
|
-
feng3d的响应式库,使用方式以及API与@vue/reactivity基本保持一致。
|
|
4
|
-
|
|
5
|
-
源码:https://gitee.com/feng3d/reactivity
|
|
6
|
-
|
|
7
|
-
文档:https://feng3d.com/reactivity
|
|
8
|
-
|
|
9
|
-
## 网站
|
|
10
|
-
|
|
11
|
-
https://feng3d.com/reactivity
|
|
12
|
-
|
|
13
|
-
## 安装
|
|
14
|
-
```
|
|
15
|
-
npm install @feng3d/reactivity
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
## 快速开始
|
|
19
|
-
|
|
20
|
-
```ts
|
|
21
|
-
import { ref, computed } from "@feng3d/reactivity";
|
|
22
|
-
|
|
23
|
-
const a = ref(1);
|
|
24
|
-
const b = ref(2);
|
|
25
|
-
const c = computed(() => a.value + b.value);
|
|
26
|
-
|
|
27
|
-
console.log(c.value); // 3
|
|
28
|
-
a.value = 3;
|
|
29
|
-
console.log(c.value); // 5
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
## 缘由
|
|
33
|
-
在feng3d引擎中使用`@vue/reactivity`代替`@feng3d/watcher`来维护数据驱动功能时发现性能严重下降。
|
|
34
|
-
|
|
35
|
-
为了解决这个问题,我重新实现了一个响应式库,并且在性能上进行了优化。
|
|
36
|
-
|
|
37
|
-
### 问题示例
|
|
38
|
-
|
|
39
|
-
示例: https://feng3d.com/reactivity/#复杂情况取值
|
|
40
|
-
|
|
41
|
-
| 运行库 | 性能(ms) | 速度(x) |
|
|
42
|
-
| --- | --- | --- |
|
|
43
|
-
| @feng3d/reactivity | 2.8 | 286 |
|
|
44
|
-
| @vue/reactivity | 801 | 1 |
|
|
45
|
-
|
|
46
|
-
### 测试代码
|
|
47
|
-
```ts
|
|
48
|
-
复杂情况取值(ref, computed, 10000);
|
|
49
|
-
|
|
50
|
-
export function 复杂情况取值(ref: <T>(value?: T) => { value: T }, computed: <T>(func: (oldValue?: T) => T) => { readonly value: T }, count: number)
|
|
51
|
-
{
|
|
52
|
-
const result = { time: undefined, values: [] };
|
|
53
|
-
|
|
54
|
-
const b = ref(2);
|
|
55
|
-
|
|
56
|
-
function 递归(depth = 10)
|
|
57
|
-
{
|
|
58
|
-
if (depth <= 0) return computed(() =>
|
|
59
|
-
{
|
|
60
|
-
return b.value
|
|
61
|
-
}).value;
|
|
62
|
-
|
|
63
|
-
return computed(() =>
|
|
64
|
-
{
|
|
65
|
-
return 递归(depth - 1) + 递归(depth - 2);
|
|
66
|
-
}).value;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const cb = computed(() =>
|
|
70
|
-
{
|
|
71
|
-
return 递归(16);
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
b.value++;
|
|
75
|
-
cb.value;
|
|
76
|
-
|
|
77
|
-
const start = performance.now();
|
|
78
|
-
for (let i = 0; i < count; i++)
|
|
79
|
-
{
|
|
80
|
-
ref(1).value++; // 添加此行代码将会导致 @vue/reactivity 版本的性能下降,而 @feng3d/reactivity 版本的性能保持不变
|
|
81
|
-
|
|
82
|
-
cb.value;
|
|
83
|
-
}
|
|
84
|
-
result.time = performance.now() - start;
|
|
85
|
-
|
|
86
|
-
result.values.push(cb.value);
|
|
87
|
-
|
|
88
|
-
return result;
|
|
89
|
-
}
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
### 分析
|
|
93
|
-
@feng3d/reactivity自下而上的使用脏标记进行维护状态,当发生变化时只会冒泡一次到父节点,全局有变化时(ref(1).value++ 标记变化)并不会触发重新计算。
|
|
94
|
-
@vue/reactivity自上而下的使用版本号进行维护状态,当全局有变化时(ref(1).value++ 标记变化)每次取值时都会遍历整个树的子节点比对版本号判断是否需要重新计算。
|
|
95
|
-
|
|
96
|
-
## 性能情况
|
|
97
|
-
### 使用不同方式维护子节点
|
|
98
|
-
|
|
99
|
-
// 修改第一个元素 `arr[0].value++;`
|
|
100
|
-
| 方式 | 性能(ms) | 速度(x) | 隐患 |
|
|
101
|
-
| --- | --- | --- | --- |
|
|
102
|
-
| 失效子节点字典 | 126 | 8.8 | 当节点失效时无法完全清除子节点,并且无法保障检查节点的顺序,导致触发过时的依赖性能或许更差,但一般情况性能最佳。 |
|
|
103
|
-
| 全量子节点链表 | 679 | 1.6 | 无 |
|
|
104
|
-
| 全量子节点字典 | 1110 | 1 | 无 |
|
|
105
|
-
| @vue/reactivity | 216 | 5.1 | 无 |
|
|
106
|
-
|
|
107
|
-
// 修改最后一个元素 `arr[9999].value++`
|
|
108
|
-
| 方式 | 性能(ms) | 速度(x) | 隐患 |
|
|
109
|
-
| --- | --- | --- | --- |
|
|
110
|
-
| 失效子节点字典 | 125 | 9.68 | 当节点失效时无法完全清除子节点,并且无法保障检查节点的顺序,导致触发过时的依赖性能或许更差,但一般情况性能最佳。 |
|
|
111
|
-
| 全量子节点链表 | 730 | 1.65 | 无 |
|
|
112
|
-
| 全量子节点字典 | 1210 | 1 | 无 |
|
|
113
|
-
| @vue/reactivity | 253 | 4.78 | 无 |
|
|
114
|
-
|
|
115
|
-
```ts
|
|
116
|
-
import { computed, ref } from "@feng3d/reactivity";
|
|
117
|
-
|
|
118
|
-
数组取值(ref, computed, 1000)
|
|
119
|
-
|
|
120
|
-
export function 数组取值(ref: <T>(value?: T) => { value: T }, computed: <T>(func: (oldValue?: T) => T) => { readonly value: T },count: number)
|
|
121
|
-
{
|
|
122
|
-
const result = { time: undefined, values: [] };
|
|
123
|
-
|
|
124
|
-
const arr:{
|
|
125
|
-
value: number;
|
|
126
|
-
}[] = new Array(10000).fill(0).map(() => ref(0));
|
|
127
|
-
|
|
128
|
-
const cb = computed(() =>
|
|
129
|
-
{
|
|
130
|
-
return arr.reduce((prev, curr) => prev + curr.value, 0);
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
const start = performance.now();
|
|
134
|
-
for (let i = 0; i < count; i++)
|
|
135
|
-
{
|
|
136
|
-
// arr[0].value++; // 修改第一个元素
|
|
137
|
-
arr[9999].value++; // 修改最后一个元素
|
|
138
|
-
cb.value;
|
|
139
|
-
}
|
|
140
|
-
result.time = performance.now() - start;
|
|
141
|
-
|
|
142
|
-
result.values.push(cb.value);
|
|
143
|
-
|
|
144
|
-
return result;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
## 为了库的简单易用性不支持以下内容
|
|
150
|
-
- markRaw
|
|
151
|
-
- shallowRef
|
|
152
|
-
- shallowReactive
|
|
153
|
-
- shallowReadonly
|
|
154
|
-
- readonly
|
|
155
|
-
- computed 中 setter
|
|
156
|
-
- __v_skip
|
|
157
|
-
|
|
158
|
-
## 扩展
|
|
1
|
+
# @feng3d/reactivity
|
|
2
|
+
|
|
3
|
+
feng3d的响应式库,使用方式以及API与@vue/reactivity基本保持一致。
|
|
4
|
+
|
|
5
|
+
源码:https://gitee.com/feng3d/reactivity
|
|
6
|
+
|
|
7
|
+
文档:https://feng3d.com/reactivity
|
|
8
|
+
|
|
9
|
+
## 网站
|
|
10
|
+
|
|
11
|
+
https://feng3d.com/reactivity
|
|
12
|
+
|
|
13
|
+
## 安装
|
|
14
|
+
```
|
|
15
|
+
npm install @feng3d/reactivity
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## 快速开始
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
import { ref, computed } from "@feng3d/reactivity";
|
|
22
|
+
|
|
23
|
+
const a = ref(1);
|
|
24
|
+
const b = ref(2);
|
|
25
|
+
const c = computed(() => a.value + b.value);
|
|
26
|
+
|
|
27
|
+
console.log(c.value); // 3
|
|
28
|
+
a.value = 3;
|
|
29
|
+
console.log(c.value); // 5
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## 缘由
|
|
33
|
+
在feng3d引擎中使用`@vue/reactivity`代替`@feng3d/watcher`来维护数据驱动功能时发现性能严重下降。
|
|
34
|
+
|
|
35
|
+
为了解决这个问题,我重新实现了一个响应式库,并且在性能上进行了优化。
|
|
36
|
+
|
|
37
|
+
### 问题示例
|
|
38
|
+
|
|
39
|
+
示例: https://feng3d.com/reactivity/#复杂情况取值
|
|
40
|
+
|
|
41
|
+
| 运行库 | 性能(ms) | 速度(x) |
|
|
42
|
+
| --- | --- | --- |
|
|
43
|
+
| @feng3d/reactivity | 2.8 | 286 |
|
|
44
|
+
| @vue/reactivity | 801 | 1 |
|
|
45
|
+
|
|
46
|
+
### 测试代码
|
|
47
|
+
```ts
|
|
48
|
+
复杂情况取值(ref, computed, 10000);
|
|
49
|
+
|
|
50
|
+
export function 复杂情况取值(ref: <T>(value?: T) => { value: T }, computed: <T>(func: (oldValue?: T) => T) => { readonly value: T }, count: number)
|
|
51
|
+
{
|
|
52
|
+
const result = { time: undefined, values: [] };
|
|
53
|
+
|
|
54
|
+
const b = ref(2);
|
|
55
|
+
|
|
56
|
+
function 递归(depth = 10)
|
|
57
|
+
{
|
|
58
|
+
if (depth <= 0) return computed(() =>
|
|
59
|
+
{
|
|
60
|
+
return b.value
|
|
61
|
+
}).value;
|
|
62
|
+
|
|
63
|
+
return computed(() =>
|
|
64
|
+
{
|
|
65
|
+
return 递归(depth - 1) + 递归(depth - 2);
|
|
66
|
+
}).value;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const cb = computed(() =>
|
|
70
|
+
{
|
|
71
|
+
return 递归(16);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
b.value++;
|
|
75
|
+
cb.value;
|
|
76
|
+
|
|
77
|
+
const start = performance.now();
|
|
78
|
+
for (let i = 0; i < count; i++)
|
|
79
|
+
{
|
|
80
|
+
ref(1).value++; // 添加此行代码将会导致 @vue/reactivity 版本的性能下降,而 @feng3d/reactivity 版本的性能保持不变
|
|
81
|
+
|
|
82
|
+
cb.value;
|
|
83
|
+
}
|
|
84
|
+
result.time = performance.now() - start;
|
|
85
|
+
|
|
86
|
+
result.values.push(cb.value);
|
|
87
|
+
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### 分析
|
|
93
|
+
@feng3d/reactivity自下而上的使用脏标记进行维护状态,当发生变化时只会冒泡一次到父节点,全局有变化时(ref(1).value++ 标记变化)并不会触发重新计算。
|
|
94
|
+
@vue/reactivity自上而下的使用版本号进行维护状态,当全局有变化时(ref(1).value++ 标记变化)每次取值时都会遍历整个树的子节点比对版本号判断是否需要重新计算。
|
|
95
|
+
|
|
96
|
+
## 性能情况
|
|
97
|
+
### 使用不同方式维护子节点
|
|
98
|
+
|
|
99
|
+
// 修改第一个元素 `arr[0].value++;`
|
|
100
|
+
| 方式 | 性能(ms) | 速度(x) | 隐患 |
|
|
101
|
+
| --- | --- | --- | --- |
|
|
102
|
+
| 失效子节点字典 | 126 | 8.8 | 当节点失效时无法完全清除子节点,并且无法保障检查节点的顺序,导致触发过时的依赖性能或许更差,但一般情况性能最佳。 |
|
|
103
|
+
| 全量子节点链表 | 679 | 1.6 | 无 |
|
|
104
|
+
| 全量子节点字典 | 1110 | 1 | 无 |
|
|
105
|
+
| @vue/reactivity | 216 | 5.1 | 无 |
|
|
106
|
+
|
|
107
|
+
// 修改最后一个元素 `arr[9999].value++`
|
|
108
|
+
| 方式 | 性能(ms) | 速度(x) | 隐患 |
|
|
109
|
+
| --- | --- | --- | --- |
|
|
110
|
+
| 失效子节点字典 | 125 | 9.68 | 当节点失效时无法完全清除子节点,并且无法保障检查节点的顺序,导致触发过时的依赖性能或许更差,但一般情况性能最佳。 |
|
|
111
|
+
| 全量子节点链表 | 730 | 1.65 | 无 |
|
|
112
|
+
| 全量子节点字典 | 1210 | 1 | 无 |
|
|
113
|
+
| @vue/reactivity | 253 | 4.78 | 无 |
|
|
114
|
+
|
|
115
|
+
```ts
|
|
116
|
+
import { computed, ref } from "@feng3d/reactivity";
|
|
117
|
+
|
|
118
|
+
数组取值(ref, computed, 1000)
|
|
119
|
+
|
|
120
|
+
export function 数组取值(ref: <T>(value?: T) => { value: T }, computed: <T>(func: (oldValue?: T) => T) => { readonly value: T },count: number)
|
|
121
|
+
{
|
|
122
|
+
const result = { time: undefined, values: [] };
|
|
123
|
+
|
|
124
|
+
const arr:{
|
|
125
|
+
value: number;
|
|
126
|
+
}[] = new Array(10000).fill(0).map(() => ref(0));
|
|
127
|
+
|
|
128
|
+
const cb = computed(() =>
|
|
129
|
+
{
|
|
130
|
+
return arr.reduce((prev, curr) => prev + curr.value, 0);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
const start = performance.now();
|
|
134
|
+
for (let i = 0; i < count; i++)
|
|
135
|
+
{
|
|
136
|
+
// arr[0].value++; // 修改第一个元素
|
|
137
|
+
arr[9999].value++; // 修改最后一个元素
|
|
138
|
+
cb.value;
|
|
139
|
+
}
|
|
140
|
+
result.time = performance.now() - start;
|
|
141
|
+
|
|
142
|
+
result.values.push(cb.value);
|
|
143
|
+
|
|
144
|
+
return result;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## 为了库的简单易用性不支持以下内容
|
|
150
|
+
- markRaw
|
|
151
|
+
- shallowRef
|
|
152
|
+
- shallowReactive
|
|
153
|
+
- shallowReadonly
|
|
154
|
+
- readonly
|
|
155
|
+
- computed 中 setter
|
|
156
|
+
- __v_skip
|
|
157
|
+
|
|
158
|
+
## 扩展
|
|
159
159
|
- 扩大被反应式的对象的类型范围,只有`Object.isExtensible`不通过的对象不被响应化。Float32Array等都允许被响应化。
|
package/dist/index.js
CHANGED
|
@@ -65,8 +65,16 @@ function noTrack(fn) {
|
|
|
65
65
|
let _shouldTrack = true;
|
|
66
66
|
function batch(dep, isRunning) {
|
|
67
67
|
if (isRunning) {
|
|
68
|
+
const index = _isRunedDeps.indexOf(dep);
|
|
69
|
+
if (index !== -1) {
|
|
70
|
+
console.warn("dep already in _isRunedDeps");
|
|
71
|
+
}
|
|
68
72
|
_isRunedDeps.push(dep);
|
|
69
73
|
} else {
|
|
74
|
+
const index = _needEffectDeps.indexOf(dep);
|
|
75
|
+
if (index !== -1) {
|
|
76
|
+
console.warn("dep already in _needEffectDeps,存在多重依赖问题。可能是由于副作用中多次修改了同一个响应式对象。");
|
|
77
|
+
}
|
|
70
78
|
_needEffectDeps.push(dep);
|
|
71
79
|
}
|
|
72
80
|
}
|
|
@@ -1620,11 +1628,89 @@ const toReactive = (value) => {
|
|
|
1620
1628
|
function isProxy(value) {
|
|
1621
1629
|
return value ? !!value[ReactiveFlags.RAW] : false;
|
|
1622
1630
|
}
|
|
1631
|
+
class ReactiveObject {
|
|
1632
|
+
constructor() {
|
|
1633
|
+
this._effectScope = new EffectScope();
|
|
1634
|
+
this._destroyCallbacks = [];
|
|
1635
|
+
}
|
|
1636
|
+
/**
|
|
1637
|
+
* 创建并运行副作用
|
|
1638
|
+
*
|
|
1639
|
+
* 功能:
|
|
1640
|
+
* 1. 将传入的函数包装为副作用
|
|
1641
|
+
* 2. 自动收集副作用中访问的响应式属性作为依赖
|
|
1642
|
+
* 3. 当依赖变化时自动重新执行副作用
|
|
1643
|
+
* 4. 在类销毁时自动停止副作用
|
|
1644
|
+
*
|
|
1645
|
+
* 使用场景:
|
|
1646
|
+
* - 监听属性变化并执行相应操作
|
|
1647
|
+
* - 自动更新UI或重新计算派生状态
|
|
1648
|
+
* - 执行清理或初始化逻辑
|
|
1649
|
+
*
|
|
1650
|
+
* @param fn 副作用函数,会在依赖变化时自动执行
|
|
1651
|
+
*
|
|
1652
|
+
* 使用示例:
|
|
1653
|
+
* ```typescript
|
|
1654
|
+
* this.effect(() => {
|
|
1655
|
+
* // 访问响应式属性,建立依赖关系
|
|
1656
|
+
* const value = reactive(this).someProperty;
|
|
1657
|
+
*
|
|
1658
|
+
* // 执行相应的逻辑
|
|
1659
|
+
* this.updateUI(value);
|
|
1660
|
+
* });
|
|
1661
|
+
* ```
|
|
1662
|
+
*/
|
|
1663
|
+
effect(fn) {
|
|
1664
|
+
let eff;
|
|
1665
|
+
this._effectScope.run(() => {
|
|
1666
|
+
eff = effect(fn);
|
|
1667
|
+
});
|
|
1668
|
+
return eff;
|
|
1669
|
+
}
|
|
1670
|
+
/**
|
|
1671
|
+
* 销毁时执行的函数
|
|
1672
|
+
* @param callback 销毁时执行的函数
|
|
1673
|
+
*/
|
|
1674
|
+
destroyCall(callback) {
|
|
1675
|
+
this._destroyCallbacks.push(callback);
|
|
1676
|
+
}
|
|
1677
|
+
/**
|
|
1678
|
+
* 销毁响应式类实例
|
|
1679
|
+
*
|
|
1680
|
+
* 执行清理操作:
|
|
1681
|
+
* 1. 执行所有注册的清理函数
|
|
1682
|
+
* 2. 停止所有副作用作用域,防止副作用继续执行
|
|
1683
|
+
* 3. 清理引用,帮助垃圾回收,防止内存泄漏
|
|
1684
|
+
*
|
|
1685
|
+
* 重要:
|
|
1686
|
+
* - 子类重写此方法时必须调用 super.destroy()
|
|
1687
|
+
* - 确保在类实例不再使用时调用此方法
|
|
1688
|
+
* - 调用后实例将无法再使用 effect() 方法
|
|
1689
|
+
*
|
|
1690
|
+
* 使用示例:
|
|
1691
|
+
* ```typescript
|
|
1692
|
+
* class MyClass extends ReactiveObject {
|
|
1693
|
+
* destroy() {
|
|
1694
|
+
* // 执行子类特定的清理逻辑
|
|
1695
|
+
* this.cleanup();
|
|
1696
|
+
*
|
|
1697
|
+
* // 必须调用父类的destroy方法
|
|
1698
|
+
* super.destroy();
|
|
1699
|
+
* }
|
|
1700
|
+
* }
|
|
1701
|
+
* ```
|
|
1702
|
+
*/
|
|
1703
|
+
destroy() {
|
|
1704
|
+
var _a2, _b2;
|
|
1705
|
+
(_a2 = this._destroyCallbacks) == null ? void 0 : _a2.forEach((item) => item());
|
|
1706
|
+
this._destroyCallbacks = null;
|
|
1707
|
+
(_b2 = this._effectScope) == null ? void 0 : _b2.stop();
|
|
1708
|
+
this._effectScope = null;
|
|
1709
|
+
}
|
|
1710
|
+
}
|
|
1623
1711
|
export {
|
|
1624
|
-
EffectReactivity,
|
|
1625
1712
|
EffectScope,
|
|
1626
|
-
|
|
1627
|
-
RefReactivity,
|
|
1713
|
+
ReactiveObject,
|
|
1628
1714
|
batchRun,
|
|
1629
1715
|
computed,
|
|
1630
1716
|
effect,
|