【Vue.js】checkboxの複数選択、個別選択、全選択機能を実装する方法

実装イメージ

チャットなどの機能で「ユーザーを選択して追加する」的な場面を想定して実装をしました。

選択済みのレコードの背景色が変わるようになっています。

ソースはコピペで動きますので、コードだけ欲しいという人は次のCodePenから持っていってください。

実際の挙動(CodePen)

See the Pen 複数チェックボックス選択で単一のclassをbindする方法 by waibandl321 (@JumCode) on CodePen.

コード解説

HTML

<div id="app">
     <table>
       <tr>
         <td>
           <input
               type="checkbox"
               id="selectAll"
               v-model="allSelected"
               @change="selectedAll()"
            >
         </td>
         <td>
           <label for="selectAll">全て選択</label>
         </td>
       </tr>
       <tr
           v-for="member in members"
           :key="member.id"
           :class="{ checked: selected(member.id) }"
           class="table-tr"
           
       >
         <td class="checkbox-td">
           <input
               type="checkbox"
               v-model="selectMembers"
               :value="member.id"
               :id="'check_' + member.id"
               @change="selected()"
            >
         </td>
         <td>
             <span style="margin-right: 24px;">
               名前:{{ member.name }}
             </span>
             <span>
               年齢:{{ member.age }}
             </span>
             <label
             :for="'check_' + member.id"
             class="checkbox-label"
           ></label>
         </td>
       </tr>
     </table>
  </div>

Vue.js用のv-modelや、ループ処理が記述してあります。大事なのは、下記の記述になりますので、それぞれどのような役割を担っているかを記載します。

  • v-model=”allSelected” : 「全て選択」checkboxのtrue or falseを判定する
  • @change=”selectedAll()” : 「全て選択」がcheckされた際の処理をmethodsで行う
  • v-for=”member in members” : メンバーの配列をループしてリストに描画する
  • :key=”member.id” : ループ処理時のkey値を指定
  • :class=”{ checked: selected(member.id) }” : 個別のリストがチェックされているかを判定し、checkedクラスを付与・削除する
  • v-model=”selectMembers” : 各リストがチェックされた状態を把握するために、全てのcheckboxのv-modelを同じにして配列で登録する
  • :value=”member.id” : checkboxの個別のvalue値
  • @change=”selected()” : 個別のリストがcheckされた際の処理をmethodsで行う

またVue.jsの処理とは関係ありませんが、チェックボックス以外のテキスト領域をクリックしてもチェック判定を行えるようにしています。<label for=””>と<input id=””>が該当します。

ここは、ユーザービリティを意識したHTMLの構造になるので、意識しておくといいと思います(結構忘れがちなので)。

Vue.js

new Vue({
  el: "#app",
  data: {
    members: [
      {id: 1, name: "name 1", age: 24},
      {id: 2, name: "name 2", age: 27},
      {id: 3, name: "name 3", age: 26},
      {id: 4, name: "name 4", age: 25}
    ],
    selectMembers: [],
    allSelected: false,
  },
  methods: {
    selected(id) {
       let select = false
       this.selectMembers.forEach(r => {
         if(r == id) {
           select = true
         }
       })
      return select
    },
    selectedAll() {
      if(this.allSelected) {
        this.selectMembers = []
        this.members.forEach(r => {
          this.selectMembers.push(r.id)
        })
      } else {
        this.selectMembers = []
      }
    },
  }
})

data

  • members : ユーザー情報を格納した配列
  • selectMembers : チェックされたリストの個別の値を格納する配列。配列で格納するために、リストのcheckboxのv-modelを全てselectMembersにしている
  • allSelected : 「全て選択」checkboxのtrue or falseの状態管理

methods

  • selected() : 個別のリストが選択された際に、<tr>にcheckedクラス付与するためにidとselectMembersの配列の値がマッチするかをチェックする処理。マッチしていればclass=”checked”を付与する。
  • selectedAll() : 全て選択がcheckされた際に、一旦selectMembersの配列を空にして、再度全てのidをselectMembers配列に登録する処理を行なっている。checkが解除された場合は、配列を空にする処理のみを行う。

関連記事

コメント

この記事へのトラックバックはありません。