はじめに
この記事は、配列要素の表示/非表示を指定するブラックリストを、Vueのv-modelデータバインディングされたcheckboxで実現した内容を記す。
動機: ホワイトリストに見えるブラックリストcheckbox
ある共有された現場リストがある。担当ごとに異なるため、人によって無関係な現場が必ず存在する。サーバが現場リストを返却したとして、フロントでは自分に関係のある現場データだけ個別に表示/非表示を指定したい。
「初期状態が表示」で、かつ「チェックが外された状態を管理」しなければならない。
ブラックリストは選択したものを除外するためのリストで、ホワイトリストは選択したものを残すためのリストである。「初期状態が表示」なのはホワイトリストのように見えるが、実際にやっていることは除外リストを作っていることになるのが普通の状況と異なる点である。
Vueデータバインディング
checkboxのtrue-valueとfalse-value
現場リストはプロパティprojectsに格納されているとする
<ul v-for="p in projects">
<li>
<label><input type="checkbox" true-value="" :false-value="p.id" v-model="excludeList">{{ p.name }}</label>
</li>
</ul>
結果は、excludeListが [] or [null] どゆこと?
配列にデータバインディングされる場合に使われる値はvalue属性
実は、true-value, false-valueが有効なのは、excludeListプロパティが配列以外の場合なのだった。
valueが指定されてないのでnullになっていたと。なるほど。これを解決するには次の通り。
<ul v-for="(p, i) in projects">
<li><label><input type="checkbox" true-value="" :false-value="p.id" v-model="excludeList[i]">{{ p.name }}</label></li>
</ul>
ここで、Vueデータバインディングで初期状態をチェック済みにするには真の場合の値が入っていないといけない。具体的には、除外リストexcludeListに初期値として["", "", "", ...]である必要がある。現場リストは可変長で、新しく現場が追加された場合は、excludeListには新しい現場に対応する値が未定義となる。未定義値と空文字列「""」は比較するとfalseだからチェック済みにならない。つまり、新しい現場の初期表示は、チェック未済になってしまう。したがって、最終的にはtrue-valueを未定義値であるundefinedにすれば良い。
<ul v-for="(p, i) in projects">
<li><label><input type="checkbox" :true-value="undefined" :false-value="p.id" v-model="excludeList[i]">{{ p.name }}</label></li>
</ul>