效果
场景: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;
}
                















