Appearance
EffectScope
effectScope
是一个函数,调用effectScope
函数会返回一个对象,其中包含了run 和stop;在run中定义的所有effect函数,在调用了scope对象的stop()方法之后,所有的依赖都被停止了。
const {effectScope,reactive,effect} = VueReactivity;
const scope = effectScope(true);
scope.run(()=>{
const state = reactive({age:13});
effect(()=>{
console.log(state.age);
});
setTimeout(()=>{
state.age++;
},1000)
});
scope.run(()=>{
const state = reactive({age:13});
effect(()=>{
console.log(state.age);
});
setTimeout(()=>{
state.age++;
},1000)
});
scope.stop(); // 停止scope
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
收集Effect
export let activeEffectScope;
class EffectScope{
active = true;
effects = [];
parent
run(fn){
if(this.active){ // 如果激活
try{
activeEffectScope = this; // 保存activeEffectScope
return fn();
}finally{
activeEffectScope = this.parent; // 还原activeEffectScope
}
}
}
}
export function recordEffectScope(effect){ // 将effect收集到activeEffectScope中
if(activeEffectScope && activeEffectScope.active){
activeEffectScope.effects.push(effect);
}
}
export class ReactiveEffect {
// 这里表示在实例上新增了active属性
public parent = null;
public deps = []
public active = true; // 这个effect默认是激活状态
constructor(public fn,public scheduler?){
recordEffectScope(this)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
实现stop、run方法
let activeEffectScope;
class EffectScope{
active = true;
effects = [];
parent = null;
run(fn){
if(this.active){ // 如果激活
try{
activeEffectScope = this; // 保存activeEffectScope
return fn();
}finally{
activeEffectScope = this.parent; // 还原activeEffectScope
}
}
}
stop(){
if(this.active){
// 创建effect的时候会将effect收集到activeEffect中
// 调用stop时依次调用effect中的stop方法
for (let i = 0, l = this.effects.length; i < l; i++) {
this.effects[i].stop();
}
this.active = false
}
}
}
export function effectScope() { // 创建effectScope
return new EffectScope();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
独立effectScope
const scope = effectScope();
scope.run(()=>{
const state = reactive({age:13});
effect(()=>{
console.log(state.age);
});
setTimeout(()=>{
state.age++;
},1000)
const innerScope = effectScope(true);
innerScope.run(()=>{
const state = reactive({age:13});
effect(()=>{
console.log(state.age);
});
setTimeout(()=>{
state.age++;
},1000)
});
});
scope.stop()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
scopes = null; // 自己可以收集 effectScope
constructor(detached = false){ // 非独立的需要收集依赖
if(!detached && activeEffectScope){ // 不是独立的就要让父亲收集effect啦~
this.parent = activeEffectScope;
(activeEffectScope.scopes || (activeEffectScope.scopes = [])).push(this)
}
}
if (this.scopes) { // stop时也要清理存储的effectScope
for (let i = 0, l = this.scopes.length; i < l; i++) {
this.scopes[i].stop()
}
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12