ただ実際やろうとすると、すべてのフィールドにchangeイベントを登録し、変更されたかどうかを監視させなければならないので面倒だ!
もっと良い方法はないかとvueの公式ドキュメントを読んでいたら良さそうなものを見つけたので、実例を交えて紹介する。
↓こんな感じの検索フォームを例に紹介する。
※ 当記事では使っているバージョンはvue@2.x系(2.5で動作確認)
watchをつかってフィールドを監視し、変更されたらイベントを発火する
普通に全フィールドをwatchするのは手間なので、formオブジェクトを使って1つにまとめる。ただ、オブジェクトをwatchしても下の階層が変更されたかどうかは監視できないので、
{ deep: true }
指定することでオブジェクトを監視できる。<main id="app">
<form>
<div>
<label>Title</label>
<input type="text" v-model="form.title">
</div>
<div>
<label>Status</label>
<label>
<input type="checkbox" value="done" v-model="form.status">
DONE
</label>
<label>
<input type="checkbox" value="progress" v-model="form.status">
PROGRESS
</label>
<label>
<input type="checkbox" value="todo" v-model="form.status">
TODO
</label>
</div>
</form>
<table>
<thead>
<tr>
<th>Title</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr
v-for="(todo, i) in filteredTodos"
:key="i"
>
<td>{{ todo.title }}</td>
<td>{{ todo.status }}</td>
</tr>
</tbody>
</table>
</main>
// import vue@2.5
const todos = [
{ title: 'test1', status: 'done' },
{ title: 'test2', status: 'progress' },
{ title: 'test3', status: 'todo' },
{ title: 'test4', status: 'done' },
{ title: 'test5', status: 'progress' },
{ title: 'test6', status: 'todo' }
]
new Vue({
el: '#app',
data () {
return {
todos: todos,
filteredTodos: [],
form: {
title: '',
status: ['done', 'progress', 'todo']
}
}
},
watch: {
// formオブジェクト内のすべての変更を監視する
form: {
handler (val, old) {
this.search()
},
deep: true
}
},
created () {
this.filteredTodos = this.todos.slice()
},
methods: {
search () {
// APIコール(GET /todos)
setTimeout(() => {
// 検索
this.filteredTodos = this.todos.slice().filter(a => {
const isMatchedTitle = this.form.title ? a.title.includes(this.form.title) : true
const isMatchedStatus = this.form.status.includes(a.status)
return isMatchedTitle && isMatchedStatus
})
}, 500)
}
}
})
formオブジェクトにtitle、statusを追加し、それを入力フィールドにバインドする。そしてwatchでhandlerと
deep: true
を指定すればOK。これでformオブジェクト内のいずれかが変更されるとhandlerが実行され、this.searchメソッドを呼ぶことができる。
参考サイト
以上
written by @bc_rikko
0 件のコメント :
コメントを投稿