チェックボックスを一括で選択・解除するボタンを実装したい時の
Vue.js(Vue3 / Composition API)での記述方法をご紹介します。
チェックボックスの全選択・全解除
コード完成版
<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タグ内 -
import { ref } from 'vue'
const selectedOptions = ref([])
チェックボックスで選択された値を格納する配列"selectedOptions"を
リアクティブ(値が更新された時に変更が検知される状態)にするため、
ref関数を使用しています。
- 参考
const onSelectAll = () => {
selectedOptions.value = options.map(option => option.id)
}
全選択の関数です。
mapメソッドでoptions(選択肢の配列)のidプロパティだけを抽出した新しい配列を
selectedOptionsに代入しています。
scriptタグ内でrefは「.value」でアクセスすることが可能です。
const onDeselectAll = () => {
selectedOptions.value = []
}
全解除の関数です。
selectedOptionsに空配列を代入することで選択した値を全解除しています。
- templateタグ内 -
<button
type="button"
class="button"
@click="onSelectAll()">
全選択
</button>
「全選択」ボタンのクリックイベントでonSelectAll関数(全選択の関数)を実行しています。
<button
type="button"
class="button"
@click="onDeselectAll()">
全解除
</button>
「全解除」ボタンのクリックイベントでonDeselectAll関数(全解除の関数)を実行しています。
<div
class="flex"
v-for="option in options"
:key="option.id">
v-forを使って、options(選択肢の配列)からデータを取り出し、繰り返しで表示します。
<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要素を関連付けることで、チェックボックス部分だけでなく、
関連するラベル(テキスト)部分をクリックしてもチェックが入るようになります。
以上です!
読んでいただきありがとうございました^^
参考記事