Quantcast
Channel: 初心者タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 21089

【Vue】チェックボックスを選択してもONのまま留める方法

$
0
0

はじめに

わかってしまえば簡単なことなのだが、
当時は解決に時間を要したので備忘録として残します。

やりたきこと

image.png

こんな感じのテーブルにて
チェックボックスをOFFにした際、確認ダイアログを表示する。

image.png

OKならそのままチェックボックスはOFFに、
キャンセルならチェックボックスはONのままに留めたい。

詰まったこと

確認ダイアログでキャンセルを選択してもチェックボックスがOFFになってしまう。

キャンセルしてもOFFになってしまう問題が出ていた時の実装が↓こちら。

実装(html)

<divid="app"><table><thead><tr><th>メールアドレス</th><th>ユーザ名</th><th>表示</th></tr></thead><tbody><trv-for="(item, index) in mailList":key="item.email"><td>{{item.email}}</td><td>{{item.name}}</td><td><inputtype="checkbox"name="checkbox"v-model="item.dispFlg"@click="onClick(index)"></td></tr></tbody></table></div>

実装(javascript)

constapp=newVue({el:'#app',data:{mailList:[{email:'sample_a@gmail.com',name:'Alice',dispFlg:true},{email:'sample_b@gmail.com',name:'Bake',dispFlg:true},{email:'sample_c@gmail.com',name:'Cassandra',dispFlg:true},{email:'sample_d@gmail.com',name:'Dick',dispFlg:true},{email:'sample_e@gmail.com',name:'Ellie',dispFlg:true}]},methods:{onClick(index){if(this.mailList[index].dispFlg){constresult=confirm(this.mailList[index].name+"のメールアドレスを無効にしますか?");if(!result){this.mailList[index].dispFlg=true;}}}}})

イケてないところ

キャンセルだった場合に、
this.mailList[index].dispFlg = true;
とすることでチェックボックスをONに戻そうとした。

しかし、これは公式ドキュメントにも書かれている通り、
配列に対してインデックスと一緒にアイテムを直接セットしてもVueは変更を検知できません。

結果、画面にはチェックボックスがOFFの状態で表示されてしまいます。

対処方法1:preventDefaultを使う

preventDefaultはイベントの伝搬を止めます。

実装(html)

<trv-for="(item, index) in mailList":key="item.email"><td>{{item.email}}</td><td>{{item.name}}</td><td><inputtype="checkbox"name="checkbox"v-model="item.dispFlg"@click="e => onClick(e,index)"></td></tr>

indexと一緒にEventオブジェクトもパラメータで渡します。

実装(javascript)

methods:{onClick(e,index){if(this.mailList[index].dispFlg){constresult=confirm(this.mailList[index].name+"のメールアドレスを無効にしますか?");if(!result){e.preventDefault();}}}}

preventDefault()でイベントの伝搬を止めることで、チェックボックスのON⇔OFFが切り替わらなくなります。

ただ、当時は実装上の都合により preventDefault()を使えなかったので頭を悩ますことになりました・・・(子コンポーネントから親コンポーネントにEventを渡せなかった)

対処方法2:key属性を与えて更新する

keyは更新前後のデータの差分抽出にVue内部で使われている特殊な属性です。

実装(html)

<divid="app"><table><thead><tr><th>メールアドレス</th><th>ユーザ名</th><th>表示</th></tr></thead><tbody:key="updateKey"><trv-for="(item, index) in mailList":key="item.email"><td>{{item.email}}</td><td>{{item.name}}</td><td><inputtype="checkbox"name="checkbox"v-model="item.dispFlg"@click="onClick(index)"></td></tr></tbody></table></div>

tbodyに対してkeyを付与します。

実装(javascript)

constapp=newVue({el:'#app',data:{mailList:[// :// 省略// :],updateKey:true},methods:{onClick(index){if(this.mailList[index].dispFlg){constresult=confirm(this.mailList[index].name+"のメールアドレスを無効にしますか?");if(!result){this.updateKey=!this.updateKey;}}}}

新たに updateKeyというデータを用意。
キャンセルの場合、 updateKeyの値を更新することでVueに <tbody>配下の再描画を促します。

結果、チェックボックスはOFFのままとなります。

まとめ

ユーザの操作に対してVueインスタンスで保持しているデータを更新させたくない場合、
preventDefaultまたは keyを試してみよう。


Viewing all articles
Browse latest Browse all 21089

Trending Articles