前几天有个博客园的朋友问小颖,小颖之前写的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);
});
}
})
}