ソリッドシード株式会社

Vue3のrefとreactiveの使い方

2022年5月30日

Nuxt3でリアクティブデータを定義する時にrefとreactiveという同じような機能があります。
公式にはどのような時にどちらの方法で定義するかの推奨を記載してないため迷う所です。
refとreactiveの適した利用の考察や使用方法をご紹介します。

refについて

refは「const hoge = ref()」と個々の変数に代入するのでモーダルのメッセージなど単一の箇所の値を扱うのに適しています。
<script>内で使用する場合は「value」を付けないと値の代入と取得ができないので注意が必要です。
ref()のカッコ内はデフォルト値が設定できます。
例えば下記のようになります。

<script setup lang="ts">
const hoge = ref(0);
//値を取得する場合
console.log(hoge.value);
//値を代入する場合
hoge.value = 99;
</script>

<template>内で使用する場合は「value」は不要になるため使用箇所によって変わるので最初は戸惑うと思います。
例えば下記のように「v-if」に「value」が不要なります。

<script setup lang="ts">
const hoge = ref(true);
</script>

<template>
    <div>
        <span v-if="hoge"></span>
    </div>
</template>

ただし、オブジェクト配列で定義した場合は「value」が必要になります。
例えば下記のようになります。

<script setup lang="ts">
const hoge = {
    is_disp: ref(true)
}
</script>

<template>
    <div>
        <span v-if="hoge.is_disp.value"></span>
    </div>
</template>

定義の仕方によって変わるので気を付ける必要があります。
もし、リアクティブデータを用途でグループ化したい場合は「reactive」の方が適していると思います。

reactiveについて

reactiveは「const hoge = reactive({ data: 0 })」とオブジェクト配列で定義するので登録などの入力フォームやエラーメッセージといった用途でグループ化したい場合に適しています。
例えば下記のようになります。

<script setup lang="ts">
const input = reactive({
    name: '',
    content: '',
});

const error = reactive({
    name_error_message: null,
    content_error_message: null
});
</script>

<template>
    <div>
        <div><input type="text" v-model="input.name" /></div>
        <div v-if="error.name_error_message !== null">{{ error.name_error_message }}</div>
        <div><input type="text" v-model="input.content" /></div>
        <div v-if="error.content_error_message !== null">{{ error.content_error_message }}</div>
    </div>
</template>

refとreactiveを比較してみましたがどうでしょうか。
用途によってうまく使い分けるとソースコードが見やすくなりコーディングもやりやすくなると思います。

投稿者:Saito