LoginSignup
5
3

More than 5 years have passed since last update.

追加したプロパティの値を変更してもv-modelで関連付けた項目が変わらない

Posted at

分かる人にはタイトルだけでアイタタタな内容かと思いますが
今日ハマったのでメモしておきます。

1. やりたいこと

ストアでリストにしてもっている項目をチェックボックス付きのリストにしたかったので、チェックボックス用のboolean項目を追加してそいつをチェックボックスのv-modelに指定しました。
全選択用のチェックボックスを作って、それが押されたら全部チェック状態が変わる、という風にしたかったのです。

最初のコード

コードを抜粋しつつ簡潔にしたものがこちら

checklist.vue(template)
 <input type="checkbox" id="checkall" @change="checkAll" v-model="checkall" />
 <label for="checkall">全選択</label>
 <ul>
   <li v-for="el in list">
     <input type="checkbox" v-model="el.checked" />
   </li>
 </ul>
checklist.vue(script)
data(){
    return {checkall:false, list:[]}
 }
 ,methods:{
   beforeOpen(event){
     // 元のリストにcheckedプロパティを追加
     event.params.sourcelist.forEach(e =>{
       this.list.push(e);
       this.list.checked=false;
     });
   }
   ,checkAll(){
      // 全選択チェックボックスの値をすべての要素に反映するのだ!
      this.list.forEach(e =>{
        e.checked=this.checkall;
      });
   }
 }

本題ではないですけどvue-js-modalを使っているので、パラメータはeventで受け取ってbeforeOpenで渡してます。

これでリスト内の全項目を全選択チェックボックスと同じ値に変更しますが、画面上のチェックボックスにうまく連動できない

原因と修正

Vue.jsのドキュメント リアクティブの探求 に記述されている内容をざっくりまとめると、
 後から勝手に追加したプロパティは追跡できないよ!
ということです。
言われてみればそりゃそうですよね。

修正

というわけで、こちらのドキュメントに書かれている通りObject.assignを使ってプロパティの多い新しいオブジェクトを作成するよう書き直しました。

修正後のコード

checklist.vue(script)
   beforeOpen(event){
     // 元のリストにcheckedプロパティを追加
     event.params.sourcelist.forEach(e =>{
       this.list.push(Object.assign({}, e, {e, selected:false}));
     });
   }

これで無事連動するようになりました!
日本語ドキュメントありがとう!

参考(文中と重複しますが)

Vue.js - ガイド - 内部 - リアクティブの探求
https://jp.vuejs.org/v2/guide/reactivity.html

5
3
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
5
3