データ変更の監視機能をもつ"watch"についてメモしたいと思います。
vueの機能には,
data,methods,computedといった機能をよく使いますが、watchという"dataやcomputedのプロパティの値を監視して、変更がある時に任意の処理を実行させることができる機能です。
基本的な使い方
【dataの値を監視】
下記のようにwatchオブジェクトの中で、
監視したい変数:
function(next(変更後の値の引数)、prev(変更前の値の引数))
と宣言することで、監視したい変数に変更があった場合には関数が実行されます。
注意したいのはv-modelを使ったテキスト入力などは一文字ずつ反映されてしまうので、一文字ずつ入力するたびに反応してしまうので.lazyなど修飾子をうまく活用しましょう。
実際に現場で使っているかはわかりませんが、非同期処理やコストの高い処理に最も便利かもしれません。
Vue.createApp({
data:function(){
return{
message:'',
}
},
watch:{
message: function(next, prev){
console.log('next:' + next )
console.log('prev:' + prev)
},
<div id ="app">
<div>
<input type="text" v-model.lzy="todoTitle" />
<p>
{{ todoTitle }}
</p>
</div>
</div>
【computedの値を監視する】
watchはdataのみだけでなく、computedの値も監視することが可能です。使い方はdataと同じように
監視したい関数:function(今回の実行結果、前回の実行結果)
と言うような形で指定することで監視することが可能です。
data: {
//省略
},
watch: {
todoTitletext: function(next, prev){
console.log('next:' +next);
console.log('prev:' +prev);
}
},
computed:{
todoTitletext: function(){
return this.todoTitlemessage= '入力は' + this.todoTitle
},
と言うような感じです。
ちょっと応用編
配列内のオブジェクトのデータ監視について
よくよくアプリケーションの構築を考えてみると、単純なテキスト入力よりもオブジェクトで利用している場合がほとんどかと思います。
そういった場合には、基本的なやり方では検知してくれないので、、
//todosのオブジェクトの中身を検知したい!!
watch: {
todos:{
handler:funciton(next,prev){
todoTitletext: function(next, prev){
console.log('todos変更あり')
},
deep: true,
}
},
といった感じで、
1.todosのオブジェクトを指定
2.オブジェクトの中でhandlerプロパティに関数を指定
3.deepプロパティを"true"に設定
することで監視しているプロパティのネストの深さに関係なく変更を検知できるようになります。
通常は値の変更はcomputedやメソッドで確認しているので、やはり非同期処理などで使うかもですね。。。
使用例【メモ】
watch関数を使ってローカルストレージへの保存
create機能を使ってローカルストレージからの呼び出し
watch:{
todos:{
handler:function(next){
window.localStorage.setItem('todos',JSON.stringify(next))
},
deep:true,
},
categories:{
handler:function(next){
window.localStorage.setItem('categories',JSON.stringify(next))
},
deep:true,
}
},
created: function() {
const todos = window.localStorage.getItem('todos')
const categories = window.localStorage.getItem('categories')
if(todos){
this.todos =JSON.parse(todos)
}
if(categories){
this.categories = JSON.parse(categories)
}
},