Vuetifyのv-data-tableの見出し（ヘッダー）にチェックボックスをつける

# はじめに

Vuetifyのv-data-tableを使って実装を進めています。
見出し行にチェックボックスをつけたい場合にどうしたかをメモしておきます。

# 完成形

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="js,result" data-user="1da2" data-slug-hash="QogjJp" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid black; margin: 1em 0; padding: 1em;" data-pen-title="Vuetify table checkbox サンプル">
  <span>See the Pen <a href="https://codepen.io/1da2/pen/QogjJp/">
  Vuetify table checkbox サンプル</a> by Shigehiro　IDANI (<a href="https://codepen.io/1da2">@1da2</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

# メモ

## データテーブルの見出しにチェックボックスをつける

まず、データテーブルの見出し行（ヘッダー）をカスタマイズしますので、
Vuetifyの[Data tables](https://vuetifyjs.com/ja/components/data-tables)のサンプルにある、「スロット: items と headers」を参考にします。

こちらは、チェックボックスのカラムが追加されていましたので、追加部分を削除し、「v-checkbox」をヘッダーの項目に移動します。

以下のような感じです。

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="js,result" data-user="1da2" data-slug-hash="aMNxeP" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid black; margin: 1em 0; padding: 1em;" data-pen-title="Vuetify Example Pen">
  <span>See the Pen <a href="https://codepen.io/1da2/pen/aMNxeP/">
  Vuetify Example Pen</a> by Shigehiro　IDANI (<a href="https://codepen.io/1da2">@1da2</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>


このままですと、チェックボックスが小さくなります。
これは見出し行でソートする場合の矢印アイコンを小さくするためのCSSの影響になります。

## チェックボックスのCSSをカスタマイズする

この状態ですと、以下の問題が発生します。

1. チェックボックスのアイコンが小さい
1. 並び替えと同時に、チェックボックスのアイコンも回ってしまう。
1. あと、Hoverするまで、チェックボックスが見えない。

このため、以下のCSSを追加します。

```css
.myCheckBox .v-icon {
  opacity: 0.6 !important;
  font-size: 24px !important;
  transform: none !important;
}
```

アイコンが小さいのは、font-sizeで対応。
アイコンが回るのは、transformで対応
Hoverまで見えないのは、opacityで対応

そして、v-checkboxのClassに「myCheckBox」を追加します。

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="js,result" data-user="1da2" data-slug-hash="rRegNZ" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid black; margin: 1em 0; padding: 1em;" data-pen-title="Vuetify Example Pen">
  <span>See the Pen <a href="https://codepen.io/1da2/pen/rRegNZ/">
  Vuetify Example Pen</a> by Shigehiro　IDANI (<a href="https://codepen.io/1da2">@1da2</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## チェックボックスが正しく動くようにする

[Checkboxes - Array
](https://vuetifyjs.com/ja/components/selection-controls#checkboxes-array)の記事を参考に調整します。

今回は見出し行を複数選択したいので、Arrayです。
checkboxにv-modelでArrayを紐付ければよいので、以下のようにします。
また、チェックをした場合に、見出し行、それぞれで異なるValueを指定できるようにします。

```vue
             <v-checkbox
              v-model="selected"
              :value="header.value"
              primary
              hide-details
              class="myCheckBox"
            ></v-checkbox>
```
このままですと、チェックボックスと見出しの部分が斜めに離れています。

![2019-03-03_17h34_00.png](https://qiita-image-store.s3.amazonaws.com/0/133291/00f0cb4d-230b-4d71-4a35-29d1a336d1fb.png)

また、チェックするのに、チェックボックスのみをクリックする必要があります。
さらに、見出しをクリックすると並べ替えが優先されてしまいます。

このため以下のように変更します。

* 見出しをクリックするとチェックを入れる
* 並び替えは、アローアイコンでのみ対応する

### 並び替えのv-onの位置を変更

並び替えのアクションである「v-on:click」は、thにバインドされていますので、これをアローアイコンを示す、v-iconに移動します。

```vue:変更前
         <th
            v-for="header in props.headers"
            :key="header.text"
            :class="['column sortable', pagination.descending ? 'desc' : 'asc', header.value === pagination.sortBy ? 'active' : '']"
            @click="changeSort(header.value)"
          >
             <v-checkbox
              v-model="selected"
              :value="header.value"
              primary
              hide-details
              class="myCheckBox"
            ></v-checkbox>

            <v-icon small>arrow_upward</v-icon>
            {{ header.text }}
          </th>
```

```vue:変更後
         <th
            v-for="header in props.headers"
            :key="header.text"
            :class="['column sortable', pagination.descending ? 'desc' : 'asc', header.value === pagination.sortBy ? 'active' : '']"
          >
             <v-checkbox
              v-model="selected"
              :value="header.value"
              primary
              hide-details
              class="myCheckBox"
            ></v-checkbox>

            <v-icon @click="changeSort(header.value)" small>arrow_upward</v-icon>
            {{ header.text }}
          </th>
```

### チェックボックスでラベル表示

名前でチェックできるように、v-checkboxのlabelプロパティに、見出し情報を移します。


```vue:変更後
         <th
            v-for="header in props.headers"
            :key="header.text"
            :class="['column sortable', pagination.descending ? 'desc' : 'asc', header.value === pagination.sortBy ? 'active' : '']"
          >
             <v-checkbox
              v-model="selected"
              :value="header.value"
              :label="header.text"
              primary
              hide-details
              class="myCheckBox"
            ></v-checkbox>
            <v-icon @click="changeSort(header.value)" small>arrow_upward</v-icon>
          </th>
```

### チェックアイコンがクリックできない。

v-checkboxのラベルはクリックできますが、チェックアイコンはクリックできません。
本家コミュニティで聞いてみたところ、自分でウォッチャーしてくださいってことでした。

「ウォッチャーって何？」と思いましたが、独自にv-on:clickを仕込めばいいようです。

v-checkboxをspanタグでくるんで、spanタグにv-on:clickを仕込んで対応しました。
また、これをしちゃうと、ラベルのクリックが反応しなくなっちゃうので、ラベルもslotで外出にしました。

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="js,result" data-user="1da2" data-slug-hash="QogjJp" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid black; margin: 1em 0; padding: 1em;" data-pen-title="Vuetify table checkbox サンプル">
  <span>See the Pen <a href="https://codepen.io/1da2/pen/QogjJp/">
  Vuetify table checkbox サンプル</a> by Shigehiro　IDANI (<a href="https://codepen.io/1da2">@1da2</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>


# 問題点

チェックボックスの色が薄いので、チェックがつくと濃くしたいなぁ。
CSSを勉強すればできるかな？