使用:
const myAge = computed({get(){},set(){},})const myAge = computed(() =>{return age.value + 10;})effect(()=>{console.log(myAge.value);})
特性:
- 此方法默认不会执行
 - 当访问属性的时候执行
 - 当依赖属性变了不会立即重新计算,而是等下次再去访问的时候才会重新计算
 
class ComputedRefImpl<T> {private _value!: T // 操作 的 valueprivate _dirty = true // 脏public readonly effect: ReactiveEffect<T>public readonly __v_isRef = true;public readonly [ReactiveFlags.IS_READONLY]: booleanconstructor(getter: ComputedGetter<T>, // 就是我们在 computed 里面写的函数private readonly _setter: ComputedSetter<T>,isReadonly: boolean) {// 计算属性默认会生成一个effectthis.effect = effect(getter, {lazy: true, // 默认初始化不执行,当取值的时候才会执行scheduler: () => { // 这个 scheduler 的作用是当我设置了 computed 里面的某个值后希望他能重新执行,就需要把_dirty 设置为trueif (!this._dirty) {this._dirty = true// 属性变化了更新trigger(toRaw(this), TriggerOpTypes.SET, 'value')}}})this[ReactiveFlags.IS_READONLY] = isReadonly}get value() { // 计算属性也要收集依赖// the computed ref may get wrapped by other proxies e.g. readonly() #3376const self = toRaw(this)if (self._dirty) {self._value = this.effect() // effect 会执行 fn 并返回结果self._dirty = false // 缓存}/*** 如果在 effect 中使用了 计算属性 计算后的值的话就需要 依赖收集* effect(()=>{* console.log(myAge.value);* })* 当访问了 value 属性时就会收集*/track(self, TrackOpTypes.GET, 'value')return self._value}set value(newValue: T) {this._setter(newValue)}}export function computed<T>(getter: ComputedGetter<T>): ComputedRef<T>export function computed<T>(options: WritableComputedOptions<T>): WritableComputedRef<T>/*** 以下两种情况:* const myAge = computed({get(){},set(){},})const myAge = computed(() =>{return age.value + 10;})* 此方法默认不会执行* 当访问属性的时候执行* 当依赖属性变了不会立即重新计算,而是等下次再去访问的时候才会重新计算** vue2 和 vue3 computer 原理是不一样的* vue2 是让 computed 依赖的属性记住 那个渲染 watcher*/export function computed<T>(getterOrOptions: ComputedGetter<T> | WritableComputedOptions<T>) {let getter: ComputedGetter<T>let setter: ComputedSetter<T>// 判断是不是一个 函数if (isFunction(getterOrOptions)) {getter = getterOrOptionssetter = __DEV__? () => {console.warn('Write operation failed: computed value is readonly')}: NOOP} else {getter = getterOrOptions.getsetter = getterOrOptions.set}return new ComputedRefImpl(getter,setter,isFunction(getterOrOptions) || !getterOrOptions.set) as any}
