效果
场景:Vue全选框在头部,子框在v-for循环内部。
实现:点击全选框,所有子项选中,再次点击取消;子项全选中,全选框自动勾选,子项并未全选,全选框不勾选;已选和全选数量统计;
实现
#1. html
<div class="checkall" :class="isCheck?'active':''" @click="clickAll"></div><span>全选</span>
<div class="card" v-for="(item, index) in tableData" :key="index">
<div class="checkitem" :class="item.isCheck?'active':''" @click="clickItem(item.id)"></div>
</div>
#2. js
data() {
return {
tableData: [],
isCheck:false,
Selected: 0,
SelectAll: 0,
}
},
mounted:{
this.init();
}
methods:{
async init(){
let res = await ...; //请求
this.tableData = res.data
this.SelectAll = res.data.length;
this.tableData = this.tableData.map(item => {
item.isCheck = false
return item
})
},
clickItem(id){
this.tableData.forEach(v=>{
v.id == id ? v.isCheck = !v.isCheck : ''
})
this.Selected = this.tableData.filter(i=>i.isCheck).length;
if(this.Selected == this.SelectAll){
this.isCheck = true;
}else{
this.isCheck?this.isCheck=false:'';
}
},
clickAll(){
this.isCheck = !this.isCheck;
if(this.isCheck){
this.tableData.forEach(v=>{
v.isCheck = true;
})
}else{
this.tableData.forEach(v=>{
v.isCheck = false;
})
}
this.Selected = this.tableData.filter(i=>i.isCheck).length;
}
}
#3. css
.checkall{
height: .16rem;
width: .16rem;
border-radius: 0.02rem;
border: 1px solid #1E77F5;
margin-right: .06rem;
}
.checkall.active{
background-color: #1E77F5;
}
.checkitem{
position: absolute;
top: .16rem;
right: .16rem;
height: .16rem;
width: .16rem;
border-radius: 0.02rem;
border: 1px solid #1E77F5;
margin-right: .06rem;
z-index: 1;
}
.checkitem.active{
background-color: #1E77F5;
}
#完整代码:
<div class="checkall" :class="isCheck?'active':''" @click="clickAll">
<span class="icon iconfont" style="color:#fff;" v-show="isCheck"></span>
</div><span>全选</span>
<div class="card" v-for="(item, index) in tableData" :key="index">
<div class="checkitem" :class="item.isCheck?'active':''" @click="clickItem(item.id)">
<span class="icon iconfont" style="color:#fff;" v-show="item.isCheck"></span>
</div>
</div>
...
data() {
return {
tableData: [],
isCheck:false,
Selected: 0,
SelectAll: 0,
}
},
mounted:{
let res = await ...; //请求后端接口
this.tableData = res.data
this.SelectAll = res.data.length;
this.tableData = this.tableData.map(item => {
item.isCheck = false
return item
})
}
methods:{
clickItem(id){
this.tableData.forEach(v=>{
v.id == id ? v.isCheck = !v.isCheck : ''
})
this.Selected = this.tableData.filter(i=>i.isCheck).length; //选完统计一下选中个数,同时调用this.tableData本身可以让视图及时更新,不再调用会出现选中没效果
if(this.Selected == this.SelectAll){
this.isCheck = true;
}else{
this.isCheck?this.isCheck=false:'';
}
},
clickAll(){
this.isCheck = !this.isCheck;
if(this.isCheck){
this.tableData.forEach(v=>{
v.isCheck = true;
})
}else{
this.tableData.forEach(v=>{
v.isCheck = false;
})
}
this.Selected = this.tableData.filter(i=>i.isCheck).length;
}
}
...
.checkall{
height: .16rem;
width: .16rem;
border-radius: 0.02rem;
border: 1px solid #1E77F5;
margin-right: .06rem;
}
.checkall.active{
background-color: #1E77F5;
}
.checkitem{
position: absolute;
top: .16rem;
right: .16rem;
height: .16rem;
width: .16rem;
border-radius: 0.02rem;
border: 1px solid #1E77F5;
margin-right: .06rem;
z-index: 1;
}
.checkitem.active{
background-color: #1E77F5;
}