0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

双方向のバインディング!v-model使う?使わない?(Vue.js,Vuex)

Last updated at Posted at 2020-06-17

#初めに
Vueインスタンス内のデータをテンプレートに表示したり、
テンプレートから入力を受けて、Vueインスタンス内のデータを更新したり、
双方向でバインディングしてくれるのですが、双方向のバインディングについて深掘りしていきます!

#v-model
双方向でバインディングと言えば、まずぱっとv-modelが出てくると思います!

<template>
  <div>
    <input type="number" v-model="apple.number" />
    <p>{{ apple.number }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      apple: {
        number:0
      }
    };
  }
};
</script>

これだけで入力した値がVueインスタンス内のリンゴの個数(apple.number)を更新してくれて、
更新された内容がしっかりテンプレートにも反映されています。
双方向のバインディングを簡単に出来ますね!

###computedのset,get
双方向のバインディングをもっと柔軟にやる方法が他にもあるので紹介します。
computedにはdefallutでgetter関数の役割を果たせしてくれていますが、setterも使うことが出来ます。

<template>
  <div>
    <input type="number" v-model="appleNumber" />
    <p>{{ apple.number }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      apple: {
        number: 0
      }
    };
  },
  computed: {
    appleNumber: {
      get() {
        return this.apple.number;
      },
      set(value) {
        this.apple.number = value;
      }
    }
  }
};
</script>

###Vuexとの連携

とくにVuexと連携させると力を発揮してくれます!

<template>
  <div>
    <input type="number" v-model="appleNumber" />
  </div>
</template>

<script>
export default {
  computed: {
    appleNumber: {
      get() {
		//storeで管理された値を取得(ゲット)する
        return this.$store.getters.appleNumber;
      },
      set(value) {
		//storeで管理された値を更新(コミット)する
        this.$store.commit('appleCalculate',value)
      }
    }
  }
};
</script>

#v-bindとv-on:input(v-on:change)
そもそもv-bindとv-on:input(v-on:change)を簡潔に書く方がv-modelなんですが、簡潔に書ける分柔軟性が欠けたりなんてことはあるあるです。
例えば、Vuex使ってかつfor文の中でv-model使ってテンプレートからVueインスタンスにindex番号指定して、storeで管理してる値を更新したいなってなった時にv-bindとv-on:input(v-on:change)を使って解決したいと思います。(v-forのkeyの値にindexは使わないで下さい。ユニークな値を使って下さい)
※下記のサンプルコードはVuex使わずに書いてます。

<template>
  <div>
    <div v-for="(fruit,index) in fruits" v-bind:key="fruit.name">
      {{ fruit.name }}:
      <input
        type="number"
        v-bind:value="fruit.number"
        v-on:input="fruitsNumber(index,$event.target.value)"
      />
      <p>{{ fruit.number }}</p>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      fruits: [
        {
          id: 1,
          name: "apple",
          number: 0
        },
        {
          id: 2,
          name: "orange",
          number: 0
        },
        {
          id: 3,
          name: "grape",
          number: 0
        }
      ]
    };
  },
  methods: {
    fruitsNumber: function(index, value) {
      this.fruits[index].number = value;
    }
  }
};
</script>

###補足 v-on:inputとv-on:changeの使い分け
inputはイメージ的に入力なので、文字が入力された時に使う。
例えばtextやtextareaに文字が入力された時

changeはイメージ的に変化なので、状態が変化した時に使う。
例えばcheckboxやradioboxやselectが変化した時

#まとめ
簡潔に書ける時はv-model
簡潔に書けない時はv-bindとv-on:input(v-on:change)
Vuexが登場したらcomputedのsetterとgetter

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?