はじめに
業務システムを作っていると、
- CSSをほとんど書かなくいい
- 使い勝手のいいコンポーネントが一通りある
- さらにドキュメントもしっかり揃っている
ということもあり、Vueを利用する場合はVuetifyを重宝します。
とくにExcel文化が根強い現場やユーザを相手にするときはDataTableを多用することになり、おかげさまでだいぶカスタマイズを行います。
そんな折、Vuetifyのバージョンが2.xへ上がりました。
それに伴いv-data-tableの使い方が若干変わり、いろいろ便利になっています。
そこで、今回は業務システムでは頻出する行クリック処理についてメモになります。
VuetifyのDataTableに行クリックを実装する
<template>
<v-container>
<v-data-table
:headers="headers"
:items="items"
@click:row="clickRow"
/>
</v-container>
</template>
<script>
export default {
name: 'DataTable',
computed: {
headers: () => [
{ text: 'id', value: 'id' },
{ text: 'name', value: 'name' },
{ text: 'point', value: 'point' }
],
items: () => [
{ id: 1, name: 'AAA', point: 100 },
{ id: 2, name: 'BBB', point: 50 },
{ id: 3, name: 'CCC', point: 25 }
]
},
methods: {
clickRow (row) {
console.log('clickRow', row)
}
}
}
</script>
これだけ。
公式サイトには特に説明がなかったと思うのですが、@click:row
が追加されていました。
以前はslotを使って「<tr @click>
」とかやってclick処理を追加していたのですが、これは助かります。
ただし、ボタン列が存在する場合には問題がある
<template>
<v-container>
<v-data-table
:headers="headers"
:items="items"
@click:row="clickRow"
>
<template v-slot:item.action="{ item }">
<v-btn @click="clickEdit(item)">編集</v-btn>
</template>
</v-data-table>
</v-container>
</template>
<script>
export default {
name: 'DataTable',
computed: {
headers: () => [
{ text: 'id', value: 'id' },
{ text: 'name', value: 'name' },
{ text: 'point', value: 'point' },
{ text: 'action', value: 'action' }
],
items: () => [
{ id: 1, name: 'AAA', point: 100 },
{ id: 2, name: 'BBB', point: 50 },
{ id: 3, name: 'CCC', point: 25 }
]
},
methods: {
clickRow (row) {
console.log('clickRow', row)
},
clickEdit (item) {
console.log('clickEdit', item)
}
}
}
</script>
単純にボタンのみの列を追加すると、
ボタンクリック ⇒ 行クリック
の順で処理が走ってしまいます。
そこで、Vueのイベントハンドリングを行う必要がありそうです。
この問題に対応するために、Vue は v-on のためにイベント修飾子(event modifiers)を提供しています。修飾子は、ドット(.)で表記されるディレクティブの接尾辞を思い返してください。
.stop
.prevent
.capture
.self
.once
.passive
.stopが使えそうですね。
行クリックとボタンクリックを実装したVuetifyのDataTable
<template>
<v-container>
<v-data-table
:headers="headers"
:items="items"
@click:row="clickRow"
>
<template v-slot:item.action="{ item }">
<v-btn @click.stop="clickEdit(item)">編集</v-btn>
</template>
</v-data-table>
</v-container>
</template>
<script>
export default {
name: 'DataTable',
computed: {
headers: () => [
{ text: 'id', value: 'id' },
{ text: 'name', value: 'name' },
{ text: 'point', value: 'point' },
{ text: 'action', value: 'action' }
],
items: () => [
{ id: 1, name: 'AAA', point: 100 },
{ id: 2, name: 'BBB', point: 50 },
{ id: 3, name: 'CCC', point: 25 }
]
},
methods: {
clickRow (row) {
console.log('clickRow', row)
},
clickEdit (item) {
console.log('clickEdit', item)
}
}
}
</script>