Vue中的checkbox全選全不選的實現
阿新 • • 發佈:2018-12-13
全選功能可以說是前端開發中非常常見的一個功能,以前的專案開發用jQuery開發比較多。最近在使用vue前端框架重構之前的專案。從jQuery到vue的轉變主要是一個思想想的轉變,是將原有的直接操作dom的思想轉變到操作資料,用資料驅動dom,也是vue框架的一個核心思想,思想轉變過來,對功能的實現自然容易理解一些。
例如下面這個簡單的demo
按照jQuery的思想來做的話,要選中全選checkbox和所有的checkbox項,分別註冊選中事件,判斷選中狀態來給相關的checkbox設定對應的狀態,這就涉及到很多的dom操作。 下面就看一下vue資料驅動dom的思想來實現這一功能。
vue資料驅動dom實現功能
<div class="checkbox"> <label for="quan"> <!-- 這裡的 $event 是將當前物件傳入進去,具體詳情請參照vue官方文件 --> <input id="quan" type="checkbox" @click="checkAll($event)"> 全選 </label> <label> <!-- v-model 雙向資料繫結命令 --> <input class="checkItem" type="checkbox" value="apple" v-model="checkData"> apple </label> <label> <input class="checkItem" type="checkbox" value="banana" v-model="checkData"> banana </label> <label> <input class="checkItem" type="checkbox" value="orange" v-model="checkData"> orange </label> </div> <script> new Vue({ el: '#app', data(){ return { checkData: [] // 雙向繫結checkbox資料陣列 } }, watch: { // 監視雙向繫結的資料陣列 checkData: { handler(){ // 資料陣列有變化將觸發此函式 if(this.checkData.length == 3){ document.querySelector('#quan').checked = true; }else { document.querySelector('#quan').checked = false; } }, deep: true // 深度監視 } }, methods: { checkAll(e){ // 點選全選事件函式 var checkObj = document.querySelectorAll('.checkItem'); // 獲取所有checkbox項 if(e.target.checked){ // 判定全選checkbox的勾選狀態 for(var i=0;i<checkObj.length;i++){ if(!checkObj[i].checked){ // 將未勾選的checkbox選項push到繫結陣列中 this.checkData.push(checkObj[i].value); } } }else { // 如果是去掉全選則清空checkbox選項繫結陣列 this.checkData = []; } } } }); </script>
利用vue的雙向資料繫結v-model命令,當勾選時,checkbox的value值會自動push到所繫結的陣列checkData中去,省去了不少對dom的操作。
如果是固定選項這樣是可以實現的,但是這種方法有一些弊端,雙向繫結陣列資料是寫死的,不太靈活,如果增加了checkbox選項,要更改wach裡繫結陣列的長度判斷。
有時候checkbox選項也是後臺動態獲取過來的,這樣也靈活一些
例如後臺資料是這樣的:
ajaxData: [{ name: 'a', value: 'apple' },{ name: 'b', value: 'banana' },{ name: 'c', value: 'orange' }]
需要先動態渲染checkbox選項,在進行資料繫結
<div id="app">
<div class="checkbox">
<label for="quan">
<!-- 這裡的 $event 是將當前物件傳入進去,具體詳情請參照vue官方文件 -->
<input id="quan" type="checkbox" @click="checkAll($event)"> 全選
</label>
<label v-for="item in ajaxData">
<!-- v-model 雙向資料繫結命令 -->
<input class="checkItem" type="checkbox" :value="item.value" v-model="checkData"> {{item.name}}
</label>
</div>
</div>
<script>
new Vue({
el: '#app',
data(){
return {
ajaxData: [{ // 後臺請求過來的資料
name: '選項1',
value: 'apple'
},{
name: '選項2',
value: 'banana'
},{
name: '選項3',
value: 'orange'
}],
checkData: [] // 雙向資料繫結的陣列
}
},
watch: {
checkData: { // 監視雙向繫結的陣列變化
handler(){
if(this.checkData.length == this.ajaxData.length){
document.querySelector('#quan').checked = true;
}else {
document.querySelector('#quan').checked = false;
}
},
deep: true
}
},
methods: {
checkAll(e){ // 點選全選事件
if(e.target.checked){
this.ajaxData.forEach((el,i)=>{
// 數組裡沒有這一個value才push,防止重複push
if(this.checkData.indexOf(el.value) == '-1'){
this.checkData.push(el.value);
}
});
}else { // 全不選選則清空繫結的陣列
this.checkData = [];
}
}
}
});
</script>