點燈坊

失くすものさえない今が強くなるチャンスよ

對 Object 建立 Reactivity

Sam Xiao's Avatar 2021-10-04

一般直覺 ref 用於 Primitive,而 reactive 用於 Object,事實上無論 refreactive$ref 都可用於 Object,且本質都是 Proxy。

Version

Vue 3.2

reactive

object000

使用 reactive 實現經典 counter。

<template>
  <button @click="onClick">+</button> {{ state.count }}
</template>

<script setup>
import { reactive } from 'vue'

let state = reactive ({
  count: 0
})

let onClick = _ => {
  console.log (state)
  state.count++
}
</script>

第 8 行

let state = reactive ({
  count: 0
})

將 Object 傳入 reactive

12 行

let onClick = _ => {
  console.log (state)
  state.count++
}
  • state 印出,可發現其本質為 Proxy
  • 可直接從 Reactive Object 取出其 property 並寫入

ref

object000

使用 ref 實現經典 counter。

<template>
  <button @click="onClick">+</button> {{ state.count }}
</template>

<script setup>
import { ref } from 'vue'

let state = ref ({
  count: 0
})

let onClick = _ => {
  console.log (state.value)
  state.value.count++
}
</script>

第 8 行

let state = ref ({
  count: 0
})

將 Object 傳入 ref

12 行

let onClick = _ => {
  console.log (state.value)
  state.value.count++
}
  • 雖然是由 ref 建立,但使用 .value 取出後,可發現其本質為 Proxy
  • 因為 ref 搭配 Object 時,其實是將 Reactive Object 包進 Reactive Reference,因此需要使用 .value 從 Reactive Reference 取出 Reactive Object 才能使用

$ref

object000

使用 $ref 實現經典 counter。

<template>
  <button @click="onClick">+</button> {{ state.count }}
</template>

<script setup>
let state = $ref ({
  count: 0
})

let onClick = _ => {
  console.log (state)
  state.count++
}
</script>

第 6 行

let state = $ref ({
  count: 0
})

將 Object 傳入 $ref

10 行

let onClick = _ => {
  console.log (state)
  state.count++
}
  • 雖然是由 $ref 建立,但不必使用 .value 取出,且其本質亦為 Proxy
  • $ref 可統一使用 Primitive 或 Object,又不必使用 .value 取出直接就是 Proxy

Conclusion

  • 若要對 Object 建立 reactivity,reactive 的確比 ref 方便,但 $ref 出現後又改變了遊戲規則,使用 Primitive 與 Object 都同樣方便
  • 不過目前 $ref 並不支援在 module 內使用,若要在 module 內使用 Object,則 reactive 會比 ref 方便