Vue.jsで複数のCheckboxを扱う

目次

はじめに

Checkboxにチェックを入れると全部に反映されていったので備忘録。

f:id:makoo5:20190929032855p:plain

その上、APIcheckedというboolean型のプロパティがない場合

※今回はあくまでチェックボックスの扱いがメインなので、追加・削除などのあるある処理は省きます。

準備

モックサーバー

APIの設計を深くまで知らないので、あくまでサンプルですが、このような形で作成しました。

モックAPIを知らない方は下記のリンクに書いておきました makoo5.hatenablog.com

{
    "todos":[{
        "name":"買い物",
        "detail":"最高"
    },{
        "name":"買い物",
        "detail":"最高"
    },{
        "name":"買い物",
        "detail":"最高"
    },{
        "name":"買い物",
        "detail":"最高"
    },{
        "name":"買い物",
        "detail":"最高"
    }]
}

vueファイル

html箇所

<div>
    <ul>
        <li v-for="(todo,index) in todos_sec" :key="index" :class="{ 'checked':todo.checked }">
            <span class="checkbox">
                <input type="checkbox" @change="toggle_sec(todo)">
            </span>
            <span class="todo_name">{{ todo.name }}</span><span class="todo_detail">{{ todo.detail }}</span>
        </li>
    </ul>
</div>

script箇所

export default {
    data(){
        return {           
            todos_sec:[]
        }
    },
    methods:{
        // ToDoのチェックボックスクリック時
        toggle(todo){
            return todo.fields.done.booleanValue = !todo.fields.done.booleanValue
        },
        axiosTodo(){
            axios.get(todosUrl)
            .then(res => {
                for(const todo of res.data.todos){
                    todo["checked"] = false
                    this.todos_sec.push(todo)
                }
            })
            .catch(error => {
                console.log(error)
            })
        },
        toggle_sec(todo){
            return todo.checked = !todo.checked
        }
    }
}

解説(主にJSファイル)

        axiosTodo(){
            axios.get(todosUrl)
            .then(res => {
                for(const todo of res.data.todos){
                    todo["checked"] = false
                    this.todos_sec.push(todo)
                }
            })

ここでは、チェックボックスのチェックの有無を確認するためのcheckedを追加しています。

    <ul>
        <li v-for="(todo,index) in todos_sec" :key="index" :class="{ 'checked':todo.checked }">
            <span class="checkbox">
                <input type="checkbox" @change="toggle_sec(todo)">
            </span>
            <span class="todo_name">{{ todo.name }}</span><span class="todo_detail">{{ todo.detail }}</span>
        </li>
    </ul>

v-forkeyにindexを指定するのは推奨されていないが、今回はユニークな値を入れてないので仕方なし

ここで重要なのは@change="toggle_sec(todo)"

選択フィールド(チェックボックスラジオボタンなど)では、変更があった時に発火するchangeイベントを使用します。

変更時に変更があったオブジェクトを引数にtoggle_sec発火することで、そのオブジェクトのみのcheckedの値が変更され、複数のチェックボックスが各々の状態で柔軟に扱うことが可能になる