状況
このようにv-checkboxを利用し、v-iconをその中に設置したいというケースはよくあると思われる。
そして一番上の要素の上矢印はクリックできないようにするという仕様。
v-checkboxでラベルの一番右まで対象になってしまっているため、何もしないとv-iconをクリックしたときに同時にcheckboxも反応してしまう。
この問題の対処法としては
<v-icon @click.stop="hoge()">mdi-arrrow-down</v-icon>
のようにstopイベント修飾子で対応可能。
だが!!
画像の左アイコンは同様にclick.stopを利用しても**propsにdisabledを指定しているため、**アイコンのクリックが行えず(これは問題ない)、チェックボックスが反応してしまう。
ここで少々詰まった。
対象のコード
<!-- チェックボックス -->
<v-checkbox v-model="hoge">
<!-- テキスト部分 -->
<template #label>
<span>{{ text }}</span>
<!-- 矢印アイコン部分 -->
<v-icon
v-if="index === 0"
color="#d3d3d3"
disabled
@click.stop="upColumn(index)"
>mdi-arrow-up</v-icon
>
<v-icon
v-else
@click.stop="upColumn(index)"
>mdi-arrow-up
</v-icon>
<!-- 最後のインデックス -->
<v-icon
v-if="index === 7"
color="#d3d3d3"
disabled
@click.stop="downColumn(index)"
>mdi-arrow-down</v-icon
>
<v-icon v-else @click.stop="downColumn(index)"
>mdi-arrow-down</v-icon
>
</template>
</v-checkbox>
問題解決
問題を掘り起こしてみると、そもそもv-checkboxのクリック範囲がv-iconの箇所に入らなければいいのではないかと気づいた。
そこでそのような方法がないか、v-checkbox APIのドキュメントをじっくり読んでみた。
Slotの箇所に下記のようなslotを発見。
append: 入力内容と入力内容の後に項目を追加します
「これだ!!」
#label(v-slot: label)をテキスト部分だけにして、#appendのtemplateを新規作成し、その中にv-iconを入れることにした。
<!-- チェックボックス -->
<v-checkbox v-model="hoge">
<!-- テキスト部分 -->
<template #label>
<span>{{ text }}</span>
</template>
<!-- 矢印アイコン部分 -->
<template #append>
<v-icon
v-if="index === 0"
color="#d3d3d3"
disabled
@click.stop="up(index)"
>mdi-arrow-up</v-icon
>
<v-icon
v-else
@click.stop="up(index)"
>mdi-arrow-up
</v-icon>
<!-- 最後のインデックス -->
<v-icon
v-if="index === 7"
color="#d3d3d3"
disabled
@click.stop="down(index)"
>mdi-arrow-down</v-icon
>
<v-icon v-else @click.stop="down(index)"
>mdi-arrow-down</v-icon
>
</template>
</v-checkbox>
できた。
まとめ
同じような問題に対処した記事が見つからなかったため、結構詰まった箇所だったが、ちゃんとVuetifyのドキュメントを読めば問題なかった。
公式ドキュメントはやっぱり大事だと学んだ、そんな良い1日でした。