2
2

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.

Vue.js 監視プロパティ

Last updated at Posted at 2020-05-07

#Vue.js 監視プロパティ

前回の記事はこちら
Vue.js 算出プロパティ

##監視プロパティとは
データやプロパティを監視して変化があった時に登録した処理を実行します

##監視プロパティの基本
jsfiddleで実際に記述しながら読むことをおすすめします。

messageプロパティのデータが変更されたら
コンソールに新旧の値を表示しましょう

以下のコードを記述します。

index/html
<div id="app">

<p>
  {{ message }}
</p>

<p>
  <input type="text" v-model:value="message">
</p>

<pre>
  {{ $data }}
</pre>

</div>

<script src ="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
index.js

var app = new Vue({
	el:'#app',
    data:{
      message:"Hello Vue.js!"
    },
  watch:{
    message:function(newValue,oldValue){
      console.log("new: %s, old: %s",newValue,oldValue)
    }
  }
})

dataオプションのmessageをwatchプロパティで監視して
入力で変更された値をconsole.logに出力します。
コンソールの記述はこちらを参考ください。
[Chrome] console.log()の色々な書き方

実行結果は以下のとおりです。
Image from Gyazo

日本語の場合は入力確定のタイミングでコンソールに結果が表示されます。

##単位変換アプリ

次にmm/m/kmを監視プロパティを使用して相互変換してみましょう

index/html
<div id="app">
<p><input type="text" v-model:value="km">km</p>
<p><input type="text" v-model:value="m">m</p>
<p><input type="text" v-model:value="mm">mm</p>
</div>
<script src ="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vu"></script>
index.js
var app = new Vue({
	el:'#app',
    data:{
      km:0,
      m:0,
      mm:0
    },
  watch:{
    km:function(value){
      /* console.log(value) */
      this.km = value
      this.m = value *1000
      this.mm = value *1000000
    },
    m:function(value){
      this.m = value
      this.km = value / 1000
      this.mm = value *1000 
    },
    mm:function(value){
      this.mm = value
      this.m = value /1000
      this.km = value /1000000
    }
   }
})

実行結果
Image from Gyazo

このようにwatchプロパティでinputの入力を監視して
km/m/mmの単位を変更することができます。

##監視プロパティと算出プロパティの比較
監視プロパティと算出プロパティは動作が似ていますので
以下のコードで検証してみましょう。

firstnameとlastnameを入力するとfullnameとして
出力されるアプリを作成します。

###監視プロパティを使用した場合

index/html
<div id="app">

<p>
  firstName <input type="text" v-model:value="firstName">
</p>

<p>
  lastName <input type="text" v-model:value="lastName">
</p>

<p>
  fullName {{ fullName }}
</p>

</div>


<script src ="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
index.js
var app = new Vue({
	el:'#app',
    data:{
      firstName:"",
      lastName:"",
      fullNAme:""
    },
  watch:{
    firstName:function(value){
      this.fullName = value +' '+ this.lastName
    },
    lastName:function(value){
      this.fullName = this.firstName +' '+ value
    }
  }
})

実行結果
Image from Gyazo

###算出プロパティを使用した場合

index/html

<div id="app">

<p>
  firstName <input type="text" v-model:value="firstName">
</p>

<p>
  lastName <input type="text" v-model:value="lastName">
</p>

<p>
  fullName {{ fullName }}
</p>

</div>


<script src ="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
index.js
var app = new Vue({
	el:'#app',
    data:{
      firstName:"",
      lastName:"",
    },
   computed:{
     fullName:function(){
       return this.firstName + " " + this.lastName
     }
   }
})

実行結果
Image from Gyazo

いずれも動作は同じなので単純な操作の場合は
算出プロパティのコードのほうが見通しがよくなります。

期待する動作に合わせて使い分けをしましょう。

##監視プロパティのオプション

監視プロパティには以下のようなオプションをつけることができます。
deep ...ネストされたオブジェクトも監視
immediate...初期読み込み時にも呼び出し

###deepオプション
配列colorsに入れた値を変更した際に
update!と表示するプログラムを作ります。

colorsの値であるnameはネストされたオブジェクトとなります。

下記のコードで確認してみましょう

index/html
<div id="app">
  <ul>
    <li v-for="color in colors">
      {{color.name}}
    </li>
  </ul>
</div>

<script src ="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
index.js

var app = new Vue({
	el:'#app',
    data:{
      colors:[
        {name:"Red"},
        {name:"Green"},
        {name:"Blue"}
      ]
    },
    wathch:{
      colors:{
        handler:function(newValue,oldValue){
          console.log('update!')
        },
        deep: true
      }
    }
})

実行結果(こちらはjsfiddleではなくファイルを作って動作確認ください)
Image from Gyazo

colorsにネストされたオブジェクトgreenのnameを
consoleからwhiteに変更するとupdateが表示されます。

deppオプションのデフォルト値はfalseなので
必要な時にtrueを設定しましょう。

###immediateオプション

deepオプションで使用したjsシートに以下を追記しましょう

index/html
<div id="app">
  <ul>
    <li v-for="color in colors">
      {{color.name}}
    </li>
  </ul>
</div>

<script src ="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
index.js

var app = new Vue({
	el:'#app',
    data:{
      colors:[
        {name:"Red"},
        {name:"Green"},
        {name:"Blue"}
      ]
    },
    wathch:{
      colors:{
        handler:function(newValue,oldValue){
          console.log('update!')
        },
        deep: true,
        immediate: true  //追加
      }
    }
})

実行結果
Image from Gyazo

immediateオプションをtrueにしたことにより
ブラウザのリロード(初期読み込み)で
console.logへの出力が確認できます。

こちらも初期値はfalseなので必要に応じて設定しましょう。

次回はclassのデータバインディングです。
Vue.js クラスとスタイルのバインディング

2
2
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
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?