🐈
Vue3でリアクティブ値を含むオブジェクトをrefでラップしたら内部の型が変わってハマった
問題
以下のようなリアクティブ値を含むオブジェクトをrefでラップした時にcomputedの型が消えてしまいハマりました。
import { ref } from "vue"
const three = ref(3)
const object = {
one: 1,
two: 2,
three: computed(() => {
return three.value
}),
}
const objectRef = ref(object)
objectRef.value = object // ここで型エラー
なぜ型が変わったのか?
公式にこんな一文があります。
If an object is assigned as a ref's value, the object is made deeply reactive with reactive(). This also means if the object contains nested refs, they will be deeply unwrapped.
DeepLで和訳するとこんな感じ。
オブジェクトがrefの値として割り当てられた場合、そのオブジェクトはreactive()でディープリアクティブにされます。これは、オブジェクトがネストしたrefを含んでいる場合、それらが深くアンラップされることも意味します。
refでオブジェクトをラップすると、オブジェクト内に含まれるrefが解除されてしまい、オブジェクト全体がリアクティブ化されてしまうらしい。
全体をリアクティブ化せずにvideo.valueのみをリアクティブ化するには、shallowRefを使えとの事。
なのでshallowRefを使用して以下のように修正します。
import { ref } from "vue"
const three = ref(3)
const object = {
one: 1,
two: 2,
three: computed(() => {
return three.value
})
}
- const objectRef = ref(object)
+ const objectRef = shallowRef(object)
これでOK。
おわりに
雰囲気でrefを使っていたせいでハマってしまいました・・・・・
公式ドキュメントはちゃんと読みましょう・・・・
Discussion