はじめに
コードを書く中で「あれ?これってref、reactiveどっちで定義すればいいんだ?オブジェクトだからreactive?」ということがあり、何も理解していなかったので備忘録として残したいと思います。(理解したとは言っていない)
以下認識誤り等ありましたら、ご指摘いただけると幸いです🙇♂
環境
- Vue3 , Nuxt3
- Composition API
- TypeScript
結論
オブジェクトだからといって、必ずしもreactiveで定義する必要はない(refでもOK)
勘違いしていたこと
学習する中で、何故かref=プリミティブ
、reactive=オブジェクト
と思い込んでおり、「オブジェクトを定義するときはreactiveで定義しなきゃ」という思考になっていました。
reactiveがプリミティブNGなだけで、refは何でもOKでした。
※プリミティブ=ざっくり、オブジェクト以外の文字列や数値などのこと
プリミティブ | オブジェクト | |
---|---|---|
ref | ◯ | ◯ |
reactive | ✕ | ◯ |
プリミティブ
<script setup lang="ts">
// reactiveは使えない
let refCount = ref(0);
let reactiveCount = reactive(0); //NG
</script>
オブジェクト
<script setup lang="ts">
// ref, reactiveどちらでもOK
let refUser = ref({
name: "Ref",
age: 20,
});
let reactiveUser = reactive({
name: "Reactive",
age: 30,
});
</script>
ref, reactiveどちらを使うか
細かい説明は割愛しますが、いろいろな方の意見を総合すると、とりあえずrefでよさそうです。(参考参照)
個人的にも、オブジェクト全体を更新する際にreactiveだとプロパティ別に更新する必要があるので、refでいいかなと思っています。
オブジェクト全体を更新する例
<template>
<div>
名前:{{ refUser.name }} 年齢:{{ refUser.age }}
</div>
<div>
名前:{{ reactiveUser.name }} 年齢:{{ reactiveUser.age }}
</div>
<div>
<button @click="refIncrement">RefAge+</button>
</div>
<div>
<button @click="reactiveIncrement">ReactiveAge+</button>
</div>
<button @click="allChange">allChange</button>
</template>
<script setup lang="ts">
let refUser = ref({
name: "Ref",
age: 20,
});
let reactiveUser = reactive({
name: "Reactive",
age: 30,
});
const refIncrement = () => {
refUser.value.age++;
};
const reactiveIncrement = () => {
reactiveUser.age++;
};
const allChange = () => {
// refだと一括更新できる
refUser.value = {
name: "Ref Taro",
age: 40,
};
// reactiveで下記はNG(リアクティブなオブジェクトではなくなる)
reactiveUser = {
name: "Reactive Taro",
age: 60,
};
// 下記のように個別更新であればOK
// reactiveUser.name = "Reactive Taro";
// reactiveUser.age = 60;
};
</script>
まとめ
- reactiveではプリミティブがNG
- オブジェクトを扱う際はref, reactiveどちらでも問題ない(個人的にはref)
参考