2-3-5 Vue3 computed

**`computed` 本质是一种基于依赖的计算缓存。**

const count = ref(1)
const plusOne = computed({
  get: () => count.value + 1,
  set: val => {
    count.value = val - 1
  }
})

plusOne.value = 1
console.log(count.value) // 0

思考一个问题:这个和普通的getter和setter有什么区别?为什么需要单独封装一个`computed` ?

export const ComputedExample03 = defineComponent({
  setup() {
    const count = ref(1)
    const plusOne = {
      get value() {
        return count.value + 1
      },
    }
    return () => {
      return <div>{plusOne.value}<button onClick={() => count.value ++}>+</button></div>
    }
  },
})

上面例子中触发`onClick` 可以使得组件刷新

`computed` 提供的是对计算的封装,让封装计算更容易。

export const ComputedExample01 = defineComponent({
  setup: () => {
    const msg = ref("hello")

    const reversedMsg = computed(() => {
      return msg.value.split("").reverse().join("")
    })

    return () => {
      return <div>
        <input onInput={(e) => {
          msg.value = (e.target as HTMLInputElement).value
        }} />
        {reversedMsg.value}
      </div>
    }
  },
})

具体的computed的定义:

function computed<T>(
  getter: () => T,
  debuggerOptions?: DebuggerOptions
): Readonly<Ref<Readonly<T>>>

当然上面的程序可以这样写,而不用computed:

export const ComputedExample02 = defineComponent({
  setup: () => {
    const msg = ref("hello")

    const reversedMsg = (msg : string) => {
      return msg.split("").reverse().join("")
    }

    return () => {
      return <div>
        <input onInput={(e) => {
          msg.value = (e.target as HTMLInputElement).value
        }} />
        {reversedMsg(msg.value)}
      </div>
    }
  },
})

保留个人观点:个人认为第二种方案语义更加清晰,因为第二种语义从语法上可以知道这是一次reversedMsg的计算。



最后, `computed` 和使用一个函数进行计算,有一个最本质的区别:

- computed会根据依赖重算

- 提供了基于依赖的缓存

例如下面程序中的`get` 只会触发一次,因为没有依赖的reactive值。

export const ComputedExample04 = defineComponent({
  setup() {
    let val = 1
    const someVal = computed({
      get: () => {
        console.log('run...')
        return val
      },
      set : () => {
        val++
      } 
    }) 
    return () => {
      return (
        <div>
          {someVal.value}
          <button onClick={() => {
            someVal.value ++
          }}>next</button>
        </div>
      )
    }
  },
})

1

猜你喜欢

转载自blog.csdn.net/m0_38066007/article/details/125049743