toRefs、proxyRef 实现

toRef

ref.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import { toReactive } from './reactive';
import { activeEffect, trackEffect, triggerEffects } from './effect';
import { createDep } from './reactiveEffect';

...

class ObjectRefImpl {
// ref 标识
public __v_isRef = true;

constructor(public _object, public _key) {}

get value() {
return this._object[this._key];
}

set value(newValue) {
this._object[this._key] = newValue;
}
}

export function toRef(object, key) {
return new ObjectRefImpl(object, key);
}

toRefs

ref.ts

1
2
3
4
5
6
7
8
9
10
...
export function toRefs(object) {
const res = {};

for (const key in object) {
res[key] = toRef(object, key);
}

return res;
}

proxyRefs

ref 类型的数据,在 template 模板中使用的时候,是不需要使用 .value 来访问的,具体可以通过 proxyRefs 来实现

ref.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
export function proxyRefs(objectWithRef) {
return new Proxy(objectWithRef, {
get(target, key, receiver) {
const r = Reflect.get(target, key, receiver);
return r.__v_isRef ? r.value : r;
},
set(target, key, value, receiver) {
const oldValue = target[key];
if (oldValue.__v_isRef) {
// 如果旧值是 ref,则需要给 ref 赋值
oldValue.value = value;
return true;
} else {
return Reflect.set(target, key, value, receiver);
}
}
});
}