【学習メモ】動かして学ぶ!Vue.js 開発入門 その6
Chapter8 データの変化を監視するとき
01 データを使って別の計算をする:算出プロパティ
マスタッシュタグの中に「JavaScriptの式」を書くのではなく「何を表示するのか」を書くほうがわかりやすくなります。それを「名前」で表したものが「computedオプション(算出プロパティ)です」。
データの値を計算して使うときは、computed
金額を入力したら、消費税込みの金額を計算する
<div id="app">
<!-- 金額を入力したら、消費税込みの金額を計算する -->
<input v-model.number="price" type="number">
<p>消費税込みの金額{{ taxIncluded }}円</p>
</div>
new Vue({
el: "#app",
data: {
price: 100
},
computed: {
// price が変わったら消費税込みの金額を算出する
taxIncluded: function () {
return this.price * 1.08;
}
}
});
結果

単位と個数を入力したら、税込み金額を計算する
<div id="app">
<!-- 単位と個数を入力したら、税込み金額を計算する -->
<input v-model.number="price" type="number"> 円 x
<input v-model.number="count" type="number"> 個
<p> 合計:{{ sum }}円</p>
<p>税込み合計:{{ taxIncluded }}円</p>
</div>
new Vue({
el: "#app",
data: {
price: 100,
count: 1
},
computed: {
// price か count が変わったら、合計金額を算出する
sum: function () {
return this.price * this.count;
},
// price が変わったら消費税込みの金額を算出する
taxIncluded: function () {
return this.sum * 1.08;
}
}
});
結果

文章を入力したら、残りの文字数を表示する
<div id="app">
<!-- 文章を入力したら、残りの文字数を表示する -->
<p>ご感想は、140文字以内でご入力ください。</p>
<textarea v-model="myText"></textarea>
<p v-bind:style="{color:computedColor}">残り{{ remaining }} 文字です。</p>
</div>
new Vue({
el: "#app",
data: {
myText: '今日は、いい天気です。'
},
computed: {
// myText の長さが変わったら、残りの文字数を算出する
remaining: function () {
return 140 - this.myText.length;
},
// remainingが変わったらcomputedColorを算出する
computedColor: function () {
col = "green";
if (this.remaining < 20) {
col = "orange";
}
if (this.remaining < 1) {
col = "red";
}
return col;
}
}
});
結果

文章を入力すると、その文字を含む項目だけ表示される
<div id="app">
<!-- 文章を入力すると、その文字を含む項目だけ表示される -->
<ul>
<input v-model="findWord">
<li v-for="item in findItems">{{ item }}</li>
</ul>
</div>
new Vue({
el: "#app",
data: {
findWord: '',
items: ['Hanako', 'Ichiro', 'Tomoko']
},
computed: {
// this.findWord が変わったら、その文字が含まれるリストを算出する
findItems: function () {
if (this.findWord) {
return this.items.filter(function (value) {
return (value.indexOf(this.findWord) > -1);
}, this);
} else {
// this.findWord が空のときは、リストをそのまま返す
return this.items;
}
}
}
});
結果

02 データの変化を監視する:監視プロパティ
データや変数の値が変わったときに、何かの処理をするには「watchオプション(監視プロパティ)」を使います。タイマーや、非同期の値など、自動的に変化する値などを監視する場合にも使います。
データの変化を監視するときは、watch
入力文字を監視して、禁止文字が入力されたらアラートを出す
<div id="app">
<!-- 入力文字を監視して、禁止文字が入力されたらアラートを出す -->
<p>禁止文字は、「{{ forbiddenText }}」</p>
<textarea v-model="inputText"></textarea>
</div>
new Vue({
el: "#app",
data: {
forbiddenText: 'ダメ',
inputText: '今日は、天気です。'
},
watch: {
// 入力された文字列を監視する
inputText: function () {
var pos = this.inputText.indexOf(this.forbiddenText);
if (pos >= 0) {
alert(this.forbiddenText + "は、入力できません。");
this.inputText = this.inputText.substr(0, pos);
}
}
}
});
結果

タイマーを作る
watch オプションは「時間を監視する」こともできます。
残りの秒数を監視して表示し、0秒になったらアラートを出す
<div id="app">
<!-- 残りの秒数を監視して表示し、0秒になったらアラートを出す -->
<p>あと {{ restSec }}秒</p>
<button v-on:click="startTimer">START</button>
</div>
new Vue({
el: "#app",
data: {
restSec: 5,
timerObj: null
},
methods: {
startTimer: function () {
// 残り5秒
this.restSec = 5;
// タイマースタート。1秒(1000ミリ秒)ごとに1秒減らす
this.timerObj = setInterval(() => {
this.restSec--;
}, 1000);
}
},
watch: {
// 残り秒数を監視する
restSec: function () {
// 0秒以下になったらアラート&タイマー停止
if (this.restSec <= 0) {
alert('制限時間です。');
clearInterval(this.timerObj);
}
}
}
});
結果

数字がくるくるとアニメーションをしながら値が増えるinput要素
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.1/TweenMax.min.js"></script>
<div id="app">
<!-- 数字がくるくるとアニメーションをしながら値が増えるinput要素 -->
<p>値は、{{ animeNumber }}です。</p>
<input v-model.numebr="myNumber" type="number">
</div>
new Vue({
el: "#app",
data: {
myNumber: 0,
tweenedNumber: 0
},
watch: {
// myNumber を監視して、もし値が変わったら実行する
myNumber: function () {
// data の tweenedNumber のプロパティを1行で myNumber まで増やす
TweenMax.to(this.$data, 1, { tweenedNumber: this.myNumber });
}
},
computed: {
// tweenedNumber が変わったら、変化中の animeNumber を算出する
animeNumber: function () {
return this.tweenedNumber.toFixed(0);
}
}
});
結果

おさらい
データが変化したら、自動的に再計算するとき
1.HTMLで表示させたいところに「プロパティ名」を指定
<p>{{ taxIncluded }} 円</p>
2.Vueインスタンスの「computed:」に、データが変化したら再計算する計算式を用意します。
computed: {
taxIncluded: function() {
return this.price * 1.08;
}
}
データが変化したら、自動的にメソッドを再実行するとき
1.HTMLのtextarea要素などに、「v-model="メソッド名"」と指定
<textarea v-model="inputText"></textarea>
2.Vueインスタンスの「data:」にそのプロパティを用意し、さらに「watch:」に、そのプロパティが変化したら再実行するメソッドを用意しておく
data: {
inputText: ""
},
watch: {
inputText: function() {
// 再実行メソッド
}
}