プログラマーノート

プログラマーの学習や雑記のメモです

【Vue.js】reactiveの値に初期値を設定する方法

はじめに

こんにちは。エンジニアの仕事をしている、たかふみです。

本日は、Vue.jsでよく使うreactiveの値に、初期値を持たせたい場合、どうするかをまとめていきます。

reactiveに初期値を持たせる場合はどういう時か

たとえば、検索フォームがあるとします。

名前とカナを入力するフォームがあるけど、クリアボタンを押した時に値がリセットされる時です。

クリアボタンを押した時、リアクティブ変数に対して、値のリセットが必要となってきます。

reactiveの値に初期値を持たせてみよう

まずは普通に、reactiveの値の初期値を設定し、

名前とふりがなが、リセットボタンを押すと初期化するようなコードを作ります。

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

// 初期データ
const initialData = {
    name:null,
    kana:null,
}
const data = reactive(initialData)

/**
 * リセット処理
 */
const reset = () => {
    // 初期化
    Object.keys(initialData).forEach(key => {
        data[key] = initialData[key]
    })
    console.log(data)
}
</script>

<template>
    <input v-model="data.name" type="text"  placeholder="なまえ">
    <input v-model="data.kana" type="text"  placeholder="ふりがな">
    <button @click="reset()">リセット</button>
</template>

なまえを【HIKAKIN】
ふりがなを【ヒカキン】
に設定しみたあと、リセットボタンを押すと無事初期化されてるでしょうか?

reest関数の最後にconsole.logを入れましたので見てみましょう。

 name: HIKAKIN
 kana: ひかきん

あれ?初期データの配列をイテレーションして、リアクティブ変数を初期値に更新したのに、何も変わっていません。

ヒカキン消えてないやん。

初期値が変わらないのはなぜか

結論から言いますと、これはシャローコピーが原因です。
シャローコピーとは、オブジェクトをコピーした際、オブジェクトのコピー元が参照になっている状態を指します。

つまり、値をコピーしても参照までコピーしてしまうのです。
とても不便ですね。

どうしたらreactive変数に初期値を持たせることができるのか

では、リアクティブ変数に初期値を持たせるにはどうしたらいいのでしょうか?

結論から言うとシャローコピーではなく、ディープコピーするとオブジェクトの参照がなくなります。
シャローコピーは、参照もコピーされてしまいますが、ディープコピーは、参照はコピーされず、単純に値のみコピーされます。

最も簡単なディープコピーの方法は、lodashを使うことでしょう。

以下のように、lodashcloneDeepを使用すればディープコピーになります。

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

// 初期データ
const initialData = {
    name:null,
    kana:null,
}
// lodashのcloneDeepを使用してみる。
const data = reactive(_.cloneDeep(initialData))

/**
 * リセット処理
 */
const reset = () => {
    // 初期化
    Object.keys(initialData).forEach(key => {
        data[key] = initialData[key]
    })
    console.log(data)
}
</script>

<template>
    <input v-model="data.name" type="text"  placeholder="なまえ">
    <input v-model="data.kana" type="text"  placeholder="ふりがな">
    <button @click="reset()">リセット</button>
</template>

console.logの内容を見ると、無事初期化されています。やったね!

 name: null
 kana: null

まとめ

vue.jsの話というか、javascriptのオブジェクトのコピーの仕方の話になりましたが、ここでハマってしまう人がいるかも知れないのでまとめておきました。

javascriptのオブジェクトの扱いでハマった時の参考にしていただければと思います。