前幾天有個博客園的朋友問小穎,小穎之前寫的vue2.0在table中實現全選和反選 、Vue.js實現checkbox的全選和反選,為什么他將里面的js復制下來,但是實現不了全選和反選。小穎當時看他給的截圖,也沒太明白,后來手動巧了一下,發現一個疑問,雖然問題是解決了,但是至於為什么小穎還是不太明白,希望有哪位vue大神看到了能幫忙解答一下,嘻嘻,小穎先在這里提前說聲:謝謝啦,嘻嘻。
我們先來看看第一種實現全選和反選的方法:直接使用 script 標簽調用vue。
<div id="app">
<input type="checkbox" v-model='checked' v-on:click='checkedAll'> 全選{{checked}}
<template v-for="(list,index) in checkboxList">
<input type="checkbox" v-model='checkList' :value="list.id"> {{list.product_inf}}
</template>
{{checkList}}
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
checkboxList: [{
'id': '1',
'product_inf': '女士銀手鏈'
}, {
'id': '2',
'product_inf': '女士銀手鐲'
}, {
'id': '3',
'product_inf': '女士銀耳環'
}],
checked: false, //全選框
checkList: []
},
methods: {
checkedAll: function() {
var _this = this;
console.log(_this.checkList);
console.log(_this.checked);
if (!_this.checked) { //實現反選
_this.checkList = [];
} else { //實現全選
_this.checkList = [];
this.checkboxList.forEach(function(item, index) {
_this.checkList.push(item.id);
});
}
}
},
watch: {
'checkList': {
handler: function(val, oldVal) {
if (val.length === this.checkboxList.length) {
this.checked = true;
} else {
this.checked = false;
}
},
deep: true
}
},
})
</script>
打印結果:


第二種實現方式:在vue腳手架環境中:
<div class="container">
<input type="checkbox" v-model='checked' v-on:click='checkedAll'> 全選{{checked}}
<template v-for="(list,index) in checkboxList">
<input type="checkbox" v-model='checkList' :value="list.id">{{list.product_inf}}
</template>
{{checkList}}
<button @click="ceshi">ceshi</button>
</div>
<script>
export default {
data() {
return {
checkboxList: [{
'id': '1',
'product_inf': '女士銀手鏈'
}, {
'id': '2',
'product_inf': '女士銀手鐲'
}, {
'id': '3',
'product_inf': '女士銀耳環'
}],
checked: false, //全選框
checkList: []
}
},
methods: {
ceshi: function() {
console.log(this.checked)
},
checkedAll: function() {
var _this = this;
console.log(_this.checkList);
console.log(_this.checked);
this.$nextTick(function() {
// DOM 現在更新了
console.log(_this.checked);
});
if (_this.checked) { //實現反選
_this.checkList = [];
} else { //實現全選
_this.checkList = [];
_this.checkboxList.forEach(function(item, index) {
_this.checkList.push(item.id);
});
}
}
},
watch: { //深度 watcher
'checkList': {
handler: function(val, oldVal) {
if (val.length === this.checkboxList.length) {
this.checked = true;
} else {
this.checked = false;
}
},
deep: true
}
}
}
</script>
打印結果:


大家看完上面的四張圖有沒有發現一個問題:
同樣是在 click 事件 checkedAll 中執行: console.log(_this.checked); 但是結果卻不一樣,第一種環境中,在修改數據之后checkedAll事件中的_this.checked立馬就變了,但是在第二種環境中,在修改數據之后checkedAll事件中的_this.checked不會立馬變,而是等到下一次調用時,才發生變化,但是在 click 事件 checkedAll 的this.$nextTick事件中,能將回調延遲到下次 DOM 更新循環之后執行。在修改數據之后立即使用它,然后等待 DOM 更新。
所以在兩種環境中,判斷全選和反選的條件也不一樣:
第一種
if (!_this.checked) { //實現反選
_this.checkList = [];
} else { //實現全選
_this.checkList = [];
this.checkboxList.forEach(function(item, index) {
_this.checkList.push(item.id);
});
}
第二種:
if (_this.checked) { //實現反選
_this.checkList = [];
} else { //實現全選
_this.checkList = [];
_this.checkboxList.forEach(function(item, index) {
_this.checkList.push(item.id);
});
}
當然也可以將第二種修改為:
checkedAll: function() {
var _this = this;
console.log(_this.checkList);
this.$nextTick(function() {
console.log(_this.checked);
// DOM 現在更新了
if (!_this.checked) { //實現反選
_this.checkList = [];
} else { //實現全選
_this.checkList = [];
_this.checkboxList.forEach(function(item, index) {
_this.checkList.push(item.id);
});
}
});
}
好啦今天的分享就到這里啦,希望大神們能幫小穎解答這個疑惑呦。。。。嘻嘻。
疑問解決啦,哈哈,原來是版本問題,之前博友給的低版本的,用了最新的版本后發現也要用Vue.nextTick方法
用新版本后,點擊事件:
checkedAll: function() {
var _this = this;
console.log(_this.checkList);
Vue.nextTick(function() {
// DOM 更新了
console.log(_this.checked);
if (!_this.checked) { //實現反選
_this.checkList = [];
} else { //實現全選
_this.checkList = [];
_this.checkboxList.forEach(function(item, index) {
_this.checkList.push(item.id);
});
}
})
}

