LoginSignup
40
41

More than 5 years have passed since last update.

v-modelに初期値をインラインから設定する

Posted at

はじめに

form の input 要素 や textarea 要素、 select 要素に双方向 (two-way) データバインディングさせるためには、
v-model を使用します😇

しかし、 Vue.js のドキュメントに以下のようなことが書いてあります。

v-model は任意の form 要素にある value、checked または selected 属性の初期値を無視します。input または textarea は常に、信頼できる情報源として Vue インスタンスを扱います。コンポーネントの data オプションの中で JavaScript 側で初期値を宣言する必要があります。

つまり、 v-model は入力の初期状態を無視するため、フォーム要素でチェックまたは選択した値を設定することはできません😿
常に Vue インスタンスデータが扱われるので、
初期値を設定するためには、data オプション( JavaScript ) 側で初期値を宣言する必要があります。

初期値をHTML側でセットしたい😿

編集画面などで、ビューをレンダリングしたときに、入力データを HTML 側から取得したいことがよくあります😥
しかし、v-model でデータバインディングしている入力要素では、初期状態が無視されるので、
初期値を設定するためには data オプションで入力値をセット(取得)しないといけません。。。
type="text" 要素だとシンプルに値を取得すれば良いのですが、 
type="radio"要素やtype="checkbox"では少し手間がかかります。
何より、例えば入力要素が動的に変動するような場合に、柔軟に対応できないと思いました。

data: function () {
  return {
    name: document.getElementById('js-name').value
  }
}

カスタムディレクティブを使う!

Vue.js は実際に HTML から初期化するようには設計されていないので、
ディレクティブを使用して値を初期化してみる!

Vue.js ではディレクティブの標準セット(v-model,v-showなど)に加えて 、
独自のカスタムディレクティブを登録することができます✌️


Vue.directive('init', {
  bind: function (el, binding, vnode) {
    vnode.context[binding.arg] = binding.value
  }
})

上記では、v-init というカスタムディレクティブを登録しています。
カスタムディレクティブにはフック関数が提供されており、 bind フックを利用して初回のみセットするように指定します👏

bind: ディレクティブが初めて対象の要素にひも付いた時に 1度だけ呼ばれます。ここで 1回だけ実行するセットアップ処理を行えます。

また、フック関数は引数を持っており、それらを利用することで初期値を設定することが可能になります。
ディレクティブフック引数についてはこちら

カスタムディレクティブv-initの例

<input type="checkbox" v-model="subscribed" v-init:subscribed="true">

v-initはコロン:の後の名前であるバインディング引数をとり、
それを Vue インスタンス上の指定された値に設定します😇
※Angular の ng-init に似ている?

これによって、v-modelでデータバインディングしている入力要素に、インラインで値を初期化することができました👏

注意点

しかし、いくつかの注意点があります😰

  • データプロパティを先に宣言する必要があります。
  • すべてJavaScriptとして評価されるため、キャメルケースのデータプロパティを設定する場合は、その指示文のキャメルケース変換にケブケースを記述する必要があります。

参考

Set Initial value to vue.js model which is directly available in HTML

40
41
4

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
40
41