本記事では、Vue.jsで作成するアプリケーションのデータやプロパティを監視して変更を検知するwatchプロパティオプションについて紹介します。
目次
watchプロパティオプション
アプリケーションではデータやプロパティなどに値を定義して、アプリケーションの状態を管理します。
定義したデータやプロパティに変更があれば、その状態に応じて処理を行ってアプリケーションに動作を与えます。
Vue.jsには、データやプロパティの変更を検知するためのウォッチャー(データを監視するための仕組み)が用意されています。
Vueインスタンスに定義するオプションオブジェクトの中で、ウォッチャーを定義するために用意されているオプションオブジェクトがwatchプロパティオプションになります。
watchプロパティは、dataオプションやcomputedオプションに定義した値を監視します。
監視している値に変更があればwatchプロパティに定義したプロパティが呼び出されますので、任意の処理を行うことができます。
wetchプロパティの書式
wetchプロパティは、次の書式で定義されます。
1 2 3 |
wetch: { プロパティ名: 関数定義 } |
「プロパティ名」がキー、「関数定義」が値になります。
「関数定義」には関数(function)を定義します。
1 2 3 4 5 |
wetch: { プロパティ名: function() { // 定義してプロパティ名のオブジェクトが変更された時の処理をここに記述 } } |
wetchプロパティの「プロパティ名」には、dataオプションやcomputedオプションに定義したプロパティ名をそのまま定義します。
例えば、dataオプションにtitleという名前のプロパティが定義されているとすれば、watchプロパティの定義は以下のようになります。
1 2 3 4 5 |
wetch: { title: function() { // 定義してプロパティ名のオブジェクトが変更された時の処理をここに記述 } } |
wetchプロパティに複数のプロパティを定義する場合は、data、computed、methodsと同様にカンマで区切ります。
1 2 3 4 5 6 7 8 9 10 11 |
wetch: { プロパティ名1: function() { // プロパティ名1が変更された時の処理をここに記述 }, プロパティ名2: function() { // プロパティ名2が変更された時の処理をここに記述 }, プロパティ名3: function() { // プロパティ名3が変更された時の処理をここに記述 } } |
wetchプロパティに変更を監視するプロパティを定義する
ここでは、wetchプロパティにプロパティを定義する例をいくつか紹介します。
値の変更を監視するプロパティを定義する
以下に示す例では、dataオプションとcomputedオプションにプロパティを定義し、定義したプロパティの値が変更された時に処理を行うためのウォッチャーを定義しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
Vue.createApp({ data: function() { return { str: '', num: 0 } }, computed: { calculatedValue: function() { return this.num * 10; } }, watch: { str: function(next, prev) { console.log(prev + 'から' + next + 'に変更されました。'); }, calculatedValue: function(newValue, oldValue) { console.log(oldValue + 'から' + newValue + 'に変更されました。'); } } }).mount('#app') |
上記の例では、watchプロパティで監視している値が変更された時に、変更前の値と変更後の値をもとにメッセージを作成してコンソールのログに出力しています。
watchプロパティに定義する関数では、引数に変更後の値と変更前の値を受け取ることができます。
オブジェクトの変更を監視するプロパティを定義する
watchプロパティでは、単純な値だけでなくオブジェクトを監視することもできます。
以下にオブジェクトをwatchプロパティで監視する例を示します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
const item = { id: 1, name: 'アイテム' }; Vue.createApp({ data: function() { return { item: item } }, watch: { item: function(next, prev) { console.log('itemが変更されました。'); } } }).mount('#app') |
上記の例のitemオブジェクトが別のオブジェクトに変更されると、watchプロパティの関数が実行されます。
しかし、itemオブジェクト自体が変更された時は変更を検知できますが、オブジェクトが持つプロパティのitem.idやitem.nameが変更されても変更を検知できません。
入れ子になったオブジェクトの変更を監視する
watchプロパティでは、オブジェクトの入れ子になったデータ(ネストされたプロパティ)の変更を監視するために、以下のようにhandlerオプションを使用します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
const item = { id: 1, name: 'アイテム' }; Vue.createApp({ data: function() { return { item: item } }, watch: { item: { handler: function(next, prev) { console.log('itemが変更されました。'); }, deep: true } } }).mount('#app') |
handlerを記述することで、入れ子になった(ネストした)データが変更された場合でも、オブジェクトの変更を検知することができるようになります。
入れ子になったデータを含めてオブジェクトを丸ごと監視する場合には、上記のようにhandlerオプションでウォッチャーの本体を指定し、deepオプションに入れ子になったオブジェクトも監視するかどうかを指定します。「true」を指定することで入れ子になったオブジェクトが監視できるようになります。(17行目)
実行結果確認用のサンプルコード
以下のコードをHTMLファイル(拡張子が.htmlのファイル)を作成して貼り付けて実行すると、IDまたは名前を変更した際にwatchプロパティに定義した関数が実行されることが確認できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<script src="https://unpkg.com/vue@next"></script> <div id="app"> <div> id: <input type="number" v-model.number="item.id" /> </div> <div> name: <input type="text" v-model="item.name" /> </div> </div> <script> const item = { id: '1', name: 'アイテム' }; Vue.createApp({ data: function() { return { item: item } }, watch: { item: { handler: function(next, prev) { console.log(`itemが変更されました。id: ${next.id} name: ${next.name}`); }, deep: true } } }).mount('#app') </script> |
入れ子になったオブジェクトの値の変更を監視する
オブジェクトの入れ子になったプロパティの値を監視する場合は、「オブジェクト.プロパティ(プロパティ.サブプロパティ)」の形式でwatchプロパティのキー部分に定義します。
入れ子になったプロパティの値を監視する場合の記述例を以下に示します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
const item = { id: 1, name: 'アイテム' }; Vue.createApp({ data: function() { return { item: item } }, watch: { 'item.id': function(next, prev) { console.log(`idが${prev}から${next}に変更されました。`); }, 'item.name': function(next, prev) { console.log(`nameが${prev}から${next}に変更されました。`); } } }).mount('#app') |
上記の例では、itemオブジェクトのidプロパティとnameプロパティをウォッチしています。
watchプロパティのキーに定義している「item.id」と「item.name」が「’」で括られています。
キーに「.」が使用できないので、クォートでくくる必要がある点には注意が必要です。
実行結果確認用のサンプルコード
HTMLファイルに貼り付けて動作を確認できるコードを以下に記載しておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<script src="https://unpkg.com/vue@next"></script> <div id="app"> <div> ID: <input type="number" v-model.number="item.id" /> </div> <div> 名前: <input type="text" v-model="item.name" /> </div> </div> <script> const item = { id: 1, name: 'アイテム' }; Vue.createApp({ data: function() { return { item: item } }, watch: { 'item.id': function(next, prev) { console.log(`が${prev}から${next}に変更されました。`); }, 'item.name': function(next, prev) { console.log(`nameが${prev}から${next}に変更されました。`); } } }).mount('#app') </script> |