目标
- 使用方式与 ref 类似,用 .value
 - 
happy path 目标
类似 ref ,用 .value
it('happy path', () => {const user = reactive({ age: 1 });const age = computed(() => {return user.age;});expect(age.value).toBe(1);});
happy path 实现
```typescript class ComputedRefImpl { private _getter: any; constructor(getter) { this._getter = getter; }
get value() { return this._getter(); } }
 
export function computed(getter) { return new ComputedRefImpl(getter); }
<a name="OzTf2"></a># 缓存功能目标```typescriptit('should compute lazily', () => {const value = reactive({ foo: 1 });const getter = vi.fn(() => {return value.foo;});const cValue = computed(getter);// lazy 懒执行expect(getter).not.toHaveBeenCalled();expect(cValue.value).toBe(1);expect(getter).toHaveBeenCalledTimes(1);// should not compute agecValue.value; // 再次触发 get,不会再计算expect(getter).toHaveBeenCalledTimes(1);// should not compute until needed 依赖的响应性对象发生改变value.foo = 2; // trigger -> effect,dirty 锁应该打开expect(getter).toHaveBeenCalledTimes(1);// now it should computeexpect(cValue.value).toBe(2); // 重新执行expect(getter).toHaveBeenCalledTimes(2);// should not compute againcValue.value;expect(getter).toHaveBeenCalledTimes(2);});
缓存实现
不会再计算,返回缓存
第一次会把值缓存,之后就返回缓存
class ComputedRefImpl {private _getter: any;private _dirty: boolean = true;// 缓存private _value: any;constructor(getter) {this._getter = getter;}get value() {// get 后上锁if(this._dirty) {this._dirty = false;this._value = this._getter();}return this._value;}}
当依赖的响应性对象发生改变
// export 把 EffectReactive 暴露出去export class EffectReactive { // ... }
class ComputedRefImpl {private _getter: any;private _dirty: boolean = true;private _value: any;private _effect: any;constructor(getter) {this._getter = getter;// 使用更低层的 ReactiveEffect 得到副作用this._effect = new ReactiveEffect(getter, ()=> {// 使用 scheduler 实现不会重复 get 和 重置缓存标记 _dirtyif (!this._dirty) {this._dirty = true;}});}get value() {// 当依赖的响应性对象发生改变 dirty = true// 这里需要引入 EffectReactiveif(this._dirty) {this._dirty = false;// this._value = this._getter();this._value = this._effect.run();}return this._value;}}
