发布时间:2023-07-28 10:30
computed可以传入一个函数,也可以传入一个对象(带有get和set方法),计算属性返回一个计算值,该值通过value属性访问,当参与计算的数据发生改变,则重新计算,不发生改变,则直接返回之前缓存的值
const { effect, reactive,computed } = VueReactivity
const state = reactive({
firstName:\'s\',
lastName:\'x\'
})
let fullName = computed(()=>{
console.log(\'runner\')
return state.firstName + state.lastName
})
console.log(fullName.value)
console.log(fullName.value)
console.log(fullName.value)
计算属性返回值可以作为属性参与effect更新
const { effect, reactive,computed } = VueReactivity
const state = reactive({
firstName:\'s\',
lastName:\'x\'
})
let fullName = computed({
get(){
return state.firstName + state.lastName
},
set(value){
state.lastName = value
}
})
fullName.value = 100
effect(()=>{
app.innerHTML = fullName.value
})
setTimeout(()=>{
state.firstName = \'x\'
},1000)
完整代码如下:
import { isFunction } from \"@vue/shared\"
import { activeEffect, trackEffects, triggerEffects,ReactiveEffect } from \"./effect\";
export function computed(getterOrOptions){
let getter = null;
let setter = null;
let fn = ()=>{
throw new Error(\"this function is onlyRead\");
}
let isGetter = isFunction(getterOrOptions)
if(isGetter){
getter = getterOrOptions
setter = fn
}
else {
getter = getterOrOptions.get
setter = getterOrOptions.set || fn
}
return new computedRefImpl(getter,setter)
}
class computedRefImpl{
private _value = null
private _dirty = true
public effect = null
public deps = null
constructor(getter,public setter){
this.effect = new ReactiveEffect(getter,()=>{
if(!this._dirty){
this._dirty = true
triggerEffects(this.deps)
}
})
}
get value(){
debugger
if(activeEffect){
// 存在effect,则进行依赖收集
trackEffects(this.deps || (this.deps = new Set()) )
}
if(this._dirty){
this._dirty = false
this._value = this.effect.run()
}
return this._value
}
set value(newValue){
this.setter(newValue)
}
}