現状
vueにはwatchという設定があって、これで値の変化を監視することができます。
しかし、ここでの設定は1つの値しか監視できず、複数の値を監視することができません。
<template lang="pug">
div
p watch test
input(type="text", v-model="$data.text1")
br
input(type="text", v-model="$data.text2")
</template>
<script>
export default {
data() {
return {
text1: '',
text2: ''
};
},
// 両方まとめてチェックする方法がない
watch: {
text1(value, oldValue) {
console.log('text1 change:', oldValue, '->', value);
},
text2(value, oldValue) {
console.log('text2 change:', oldValue, '->', value);
}
}
};
</script>
解決方法
複数の値をチェックする方法は僕が知っている限りでは2種類あります。
watch関数を使う方法
watch関数に評価関数を設定できるので、watchオプションを使わず、直接watch関数を実行する方法です。
<template lang="pug">
div
p watch test
input(type="text", v-model="$data.text1")
br
input(type="text", v-model="$data.text2")
</template>
<script>
export default {
data() {
return {
text1: '',
text2: ''
};
},
created() {
this.$watch(
// 2つのプロパティを含めた値を評価させる
() => [this.$data.text1, this.$data.text2],
// valueやoldValueの型は上で返した配列になる
(value, oldValue) => {
console.log('[text1, text2] change:', oldValue, '->', value);
}
);
}
};
</script>
この方法はwatchプロパティに含めることが出来ないので、必然的に監視ロジックを他の場所に書かざるを得なくなり、コードを探すのが少し大変になるかもしれません。
算出プロパティを監視する方法
computedで算出された値も監視することができるので、監視したい値をcomputedで計算し、それを監視する方法です。
<template lang="pug">
div
p watch test
input(type="text", v-model="$data.text1")
br
input(type="text", v-model="$data.text2")
</template>
<script>
export default {
data() {
return {
text1: '',
text2: ''
};
},
computed: {
_allTexts() {
return [this.$data.text1, this.$data.text2];
}
},
watch: {
// computedで計算されたものを監視できる
_allTexts(value, oldValue) {
console.log('allTexts change:', oldValue, '->', value);
}
}
};
</script>
この方法はwatchプロパティに含めることはできますが、新しい名前を考えないといけない上、value, oldValueの中身はcomputedの方を見ないといけないのでコードが離れてしまう欠点があります。
まとめ
正直どっちの方法も微妙なところではありますが、computedを使って監視するのはあんまりよくないかなと思っています。
computedは他の用途でも使われると思いますし、複数の値をwatchしたいだけという理由でプロパティを増やしたくないなという気持ちがあります。
また僕の場合はcomputedは_をつけてdataやpropsと差別化してますが、普通はそんなことをしないようなので、もはやどこの属性のものをwatchしているのか分からなくなっちゃんじゃないかなという懸念もあります。
(ちなみにですが、watchは'$data.text1'(val, oldVal) { ... }
のように$data
や$props
をつけて監視することもできます。気持ち悪いですが)
まぁ最終的には使いやすい方を使うでいいと思います。