1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

qnoteAdvent Calendar 2024

Day 20

【Vue3】checkbox(チェックボックス) 〜 全選択・全解除 〜

Last updated at Posted at 2024-12-19

チェックボックスを一括で選択・解除するボタンを実装したい時の
Vue.js(Vue3 / Composition API)での記述方法をご紹介します。

チェックボックスの全選択・全解除

こんな感じで動きます。
checkbox_allselect_deselect.gif

コード完成版

CheckBox.vue
<script setup>
import { ref } from 'vue'

// 補足1参照
const selectedOptions = ref([])

// 選択肢の定数は別ファイルに切り出すことをお勧めしますが、ここでは同じファイル内に記述します
const options = [
  { id: 1, value: '選択肢1' },
  { id: 2, value: '選択肢2' },
  { id: 3, value: '選択肢3' },
  { id: 4, value: '選択肢4' },
]

// 補足2参照
const onSelectAll = () => {
  selectedOptions.value = options.map(option => option.id)
}

// 補足3参照
const onDeselectAll = () => {
  selectedOptions.value = []
}

</script>

<template>
  <div class="margin">
    <label> 選択項目 </label>
    <div class="flex">
      <!-- 補足4参照 -->
      <button
        type="button"
        class="button"
        @click="onSelectAll()">
        全選択
      </button>
      <!-- 補足5参照 -->
      <button
        type="button"
        class="button"
        @click="onDeselectAll()">
        全解除
      </button>
    </div>
    <!-- 補足6参照 -->
    <div
      class="flex"
      v-for="option in options"
      :key="option.id">
      <!-- 補足7参照 -->
      <label
        :for="`selected_${option.id}`">
      <input
        v-model="selectedOptions"
        :id="`selected_${option.id}`"
        type="checkbox"
        :value="option.id" />
        {{ option.value }}
      </label>
    </div>
  </div>
</template>

<style>
/* cssは別ファイルからの読み込みを推奨しますが、ここでは同じファイル内に記述します */
.margin {
  margin: 2em;
}
.flex {
  display: flex;
  gap: 10px;
  margin: 5px 0;
}
.button {
  border: solid 1px #333;
  border-radius: 10%;
  padding: 2px 5px;
}
</style>


各セクションの補足説明です。

- scriptタグ内 -

補足1
import { ref } from 'vue'

const selectedOptions = ref([])

チェックボックスで選択された値を格納する配列"selectedOptions"を
リアクティブ(値が更新された時に変更が検知される状態)にするため、
ref関数を使用しています。


補足2
const onSelectAll = () => {
  selectedOptions.value = options.map(option => option.id)
}

全選択の関数です。
mapメソッドでoptions(選択肢の配列)のidプロパティだけを抽出した新しい配列を
selectedOptionsに代入しています。
scriptタグ内でrefは「.value」でアクセスすることが可能です。


補足3
const onDeselectAll = () => {
  selectedOptions.value = []
}

全解除の関数です。
selectedOptionsに空配列を代入することで選択した値を全解除しています。


- templateタグ内 -

補足4
<button
  type="button"
  class="button"
  @click="onSelectAll()">
  全選択
</button>

「全選択」ボタンのクリックイベントでonSelectAll関数(全選択の関数)を実行しています。


補足5
<button
  type="button"
  class="button"
  @click="onDeselectAll()">
  全解除
</button>

「全解除」ボタンのクリックイベントでonDeselectAll関数(全解除の関数)を実行しています。


補足6
<div
class="flex"
v-for="option in options"
:key="option.id">

v-forを使って、options(選択肢の配列)からデータを取り出し、繰り返しで表示します。


補足7
<label
  :for="`selected_${option.id}`">
<input
  v-model="selectedOptions"
  :id="`selected_${option.id}`"
  type="checkbox"
  :value="option.id" />
  {{ option.value }}
</label>

input要素にv-modelを利用することで、入力値とデータを同期することができます。
チェックした順にvalue属性の値が配列"selectedOptions"に追加されていきます。


そして、label要素とinput要素を明示的に関連付けるために、 input要素にid属性を、label要素にfor属性を追加しています。 (forとidの値は同じにします)

または、inputをlabelの入れ子にすることでも、関連づけることが可能です。
その場合、forおよびid属性は必要ありません。
(上記ではforおよびidを追加していますが、追加しなくても同じく動作します)

label要素とinput要素を関連付けることで、チェックボックス部分だけでなく、
関連するラベル(テキスト)部分をクリックしてもチェックが入るようになります。


以上です!
読んでいただきありがとうございました^^

参考記事

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?