1. 程式人生 > >Vue中的checkbox全選全不選的實現

Vue中的checkbox全選全不選的實現

全選功能可以說是前端開發中非常常見的一個功能,以前的專案開發用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>