vue基于element-ui的三級(jí)CheckBox復(fù)選框功能的實(shí)現(xiàn)代碼
最近vue項(xiàng)目需要用到三級(jí)CheckBox復(fù)選框,需要實(shí)現(xiàn)全選反選不確定三種狀態(tài)。但是element-ui table只支持多選行,并不能支持三級(jí)及以上的多選,下面通過(guò)本文給大家講解實(shí)現(xiàn)方法。
效果圖預(yù)覽:

首先是頁(yè)面布局,當(dāng)然也可已使用table,但是自己用flex布局后面更容易增刪改查其他功能
<div class="deliverySetting-table">
<div class="table-head">
<div class="selection">
<el-checkbox :indeterminate="indeterminate" v-model="ischeckAll" @change="handleCheckAllChange"></el-checkbox>
</div>
<div class="width185">分區(qū)名稱</div>
<div class="width265">國(guó)家</div>
<div>派送商</div>
</div>
<div class="table-body" v-for="(partition,partitionIndex) in distributorsInfo" :key="partitionIndex">
<div class="selection">
<p><el-checkbox :indeterminate="partition.indeterminate" v-model="partition.selected" @change="handleCheckedCountryAllChange(partitionIndex,partition.partitionId,$event)" :key="partitionIndex"></el-checkbox></p>
</div>
<div class="width185"><p>{{ partition.partitionName }}</p></div>
<div class="width265">
<el-checkbox v-for="country in partition.country" v-model="country.selected" @change="handleCheckedCountryChange(partitionIndex,country.id,partition.partitionId,$event)" :label="country" :key="country.id">{{country.fieldName}}</el-checkbox>
</div>
<div>
<p v-for="(item,index) in partition.country" :key="index">
{{ item.distributors }}
</p>
</div>
</div>
</div>
接下來(lái)是數(shù)據(jù)結(jié)構(gòu),自定義的,可以更后臺(tái)商議,但是字段indeterminate(顯示不確定狀態(tài)~符號(hào)),selected(CheckBox選中狀態(tài))一定要讓后臺(tái)加入到data中,其他可以按照后臺(tái)數(shù)據(jù)來(lái)。
distributorsInfo:[
{ partitionName:'1區(qū)',selected:false,partitionId:1,isIndeterminate:false,
country:[
{ id: "1",fieldName: "奧地利",fieldTableName: "奧地利",distributors:'UPS',selected: false},
{ id: "2",fieldName: "芬蘭",fieldTableName: "芬蘭",distributors:'UPS',selected: false},
{ id: "3",fieldName: "意大利",fieldTableName: "意大利",distributors:'UPS',selected: false},
{ id: "4",fieldName: "葡萄牙",fieldTableName: "葡萄牙",distributors:'UPS',selected: false},
{ id: "9",fieldName: "西班牙",fieldTableName: "西班牙",distributors:'UPS',selected: false},
{ id: "10",fieldName: "瑞典",fieldTableName: "瑞典",distributors:'UPS',selected: false},]
},
{ partitionName:'2區(qū)',selected:false,partitionId:2,isIndeterminate:false,
country:[
{ id: "5",fieldName: "丹麥",fieldTableName: "單買",distributors:'',selected: false},
{ id: "6",fieldName: "法國(guó)",fieldTableName: "法國(guó)",distributors:'',selected: false},]
},
{ partitionName:'3區(qū)',selected:false,partitionId:3,isIndeterminate:false,
country:[
{ id: "7",fieldName: "德國(guó)",fieldTableName: "德國(guó)",distributors:'YODEL',selected: false},
{ id: "8",fieldName: "瑞士",fieldTableName: "瑞士",distributors:'DPD',selected: false}]
}
],
ischeckAll:false,//一級(jí)全選狀態(tài)
因?yàn)榇颂幨侨?jí)復(fù)選,所以函數(shù)為三個(gè)change,具體有詳細(xì)注釋可以查看
handleCheckAllChange(e){//一級(jí)change事件
this.ischeckAll = e
if(e == true){
this.indeterminate = false
for(var i=0,len=this.distributorsInfo.length; i<len; i++){ //二級(jí)全選反選不確定
this.distributorsInfo[i].selected = e
for(var j=0,len1=this.distributorsInfo[i].country.length; j<len1; j++){
this.distributorsInfo[i].country[j].selected = e
}
}
}else{
this.indeterminate = false
for(var i=0,len=this.distributorsInfo.length; i<len; i++){ //三級(jí)全選反選不確定
this.distributorsInfo[i].selected = e
for(var j=0,len1=this.distributorsInfo[i].country.length; j<len1; j++){
this.distributorsInfo[i].country[j].selected = e
}
}
}
},
handleCheckedCountryAllChange(index, topId, e){//二級(jí)change事件
this.distributorsInfo[index].selected = e//二級(jí)勾選后,子級(jí)全部勾選或者取消
if(e == false) this.distributorsInfo[index].indeterminate = false //去掉二級(jí)不確定狀態(tài)
var childrenArray = this.distributorsInfo[index].country
if(childrenArray)
for(var i=0,len=childrenArray.length; i<len; i++)
childrenArray[i].selected = e
this.getIsCheckAll()
},
handleCheckedCountryChange(topIndex, sonId, topId, e){//三級(jí)change事件
var childrenArray = this.distributorsInfo[topIndex].country
var tickCount = 0, unTickCount = 0, len = childrenArray.length
for(var i = 0; i < len; i++){
if(sonId == childrenArray[i].id) childrenArray[i].selected = e
if(childrenArray[i].selected == true) tickCount++
if(childrenArray[i].selected == false) unTickCount++
}
if(tickCount == len) {//三級(jí)級(jí)全勾選
this.distributorsInfo[topIndex].selected = true
this.distributorsInfo[topIndex].indeterminate = false
} else if(unTickCount == len) {//三級(jí)級(jí)全不勾選
this.distributorsInfo[topIndex].selected = false
this.distributorsInfo[topIndex].indeterminate = false
} else {
this.distributorsInfo[topIndex].selected = false
this.distributorsInfo[topIndex].indeterminate = true //添加二級(jí)不確定狀態(tài)
}
this.getIsCheckAll()
},
getIsCheckAll(){
var tickCount = 0, unTickCount = 0, ArrLength = this.distributorsInfo.length
for(var j=0; j<ArrLength; j++){//全選checkbox狀態(tài)
if(this.distributorsInfo[j].selected == true) tickCount++
if(this.distributorsInfo[j].selected == false) unTickCount++
}
if(tickCount == ArrLength) {//二級(jí)全勾選
this.ischeckAll = true
this.indeterminate = false
} else if(unTickCount == ArrLength) {//二級(jí)全不勾選
this.ischeckAll = false
this.indeterminate = false
} else {
this.ischeckAll = false
this.indeterminate = true //添加一級(jí)不確定狀態(tài)
}
},
以下是頁(yè)面完整組件代碼可以使用預(yù)覽
<template>
<div class="deliverySetting">
<div class="deliverySetting-btn">
<div class="tabs-btn ac">
<input type="button" value="分配派送商" @click="showSetDistributorDailog">
</div>
<div class="tabs-btn ac">
<input type="button" value="取消分配" @click="showCancelDistributorDailog">
</div>
</div>
<div class="deliverySetting-table">
<div class="table-head">
<div class="selection">
<el-checkbox :indeterminate="indeterminate" v-model="ischeckAll" @change="handleCheckAllChange"></el-checkbox>
</div>
<div class="width185">分區(qū)名稱</div>
<div class="width265">國(guó)家</div>
<div>派送商</div>
</div>
<div class="table-body" v-for="(partition,partitionIndex) in distributorsInfo" :key="partitionIndex">
<div class="selection">
<p><el-checkbox :indeterminate="partition.indeterminate" v-model="partition.selected" @change="handleCheckedCountryAllChange(partitionIndex,partition.partitionId,$event)" :key="partitionIndex"></el-checkbox></p>
</div>
<div class="width185"><p>{{ partition.partitionName }}</p></div>
<div class="width265">
<el-checkbox v-for="country in partition.country" v-model="country.selected" @change="handleCheckedCountryChange(partitionIndex,country.id,partition.partitionId,$event)" :label="country" :key="country.id">{{country.fieldName}}</el-checkbox>
</div>
<div>
<p v-for="(item,index) in partition.country" :key="index">
{{ item.distributors }}
</p>
</div>
</div>
</div>
<!-- 分配派送商dailog -->
<el-dialog title="分配派送商" :visible.sync="setDistributorDailog" width="480px">
<el-form :model="distributorForm" :rules="rules" class="setDistributorDailog">
<el-form-item label="派送代理商" label-width="120px">
<el-input v-model="distributorForm.vendorName" auto-complete="off" placeholder="請(qǐng)輸入供應(yīng)商名稱"></el-input>
</el-form-item>
<el-form-item label="末端派送商" prop="senderName" label-width="120px">
<el-select v-model="distributorForm.senderName"
filterable
allow-create
default-first-option
placeholder="請(qǐng)選派送商名稱">
<el-option label="派送商1" value="shanghai"></el-option>
<el-option label="派送商2" value="beijing"></el-option>
</el-select>
</el-form-item>
<el-form-item label="派送商官網(wǎng)" prop="website" label-width="120px">
<el-input v-model="distributorForm.website" auto-complete="off" placeholder="請(qǐng)輸入派送商官網(wǎng)"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="setDistributorDailog = false">取 消</el-button>
<el-button type="primary" @click="setDistributorDailog = false">確 定</el-button>
</div>
</el-dialog>
<!-- 取消分配派送商 -->
<el-dialog title="停止提示" :visible.sync="cancelDistributorDailog" :modal="false" width="480px" custom-class="stop-coupon-dialog">
<p><br></p>
<p class="ac f16">您確定要取消對(duì)的派送分配嗎?</p>
<p><br></p>
<span slot="footer" class="dialog-footer">
<el-button @click="cancelDistributorDailog = false">取 消</el-button>
<el-button type="primary" @click="cancelDistributorDailog=false">確 定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
export default {
name:'deliverySetting',
components: {
},
props:{
},
data() {
return {
distributorsInfo:[
{ partitionName:'1區(qū)',selected:false,partitionId:1,isIndeterminate:false,
country:[
{ id: "1",fieldName: "奧地利",fieldTableName: "奧地利",distributors:'UPS',selected: false},
{ id: "2",fieldName: "芬蘭",fieldTableName: "芬蘭",distributors:'UPS',selected: false},
{ id: "3",fieldName: "意大利",fieldTableName: "意大利",distributors:'UPS',selected: false},
{ id: "4",fieldName: "葡萄牙",fieldTableName: "葡萄牙",distributors:'UPS',selected: false},
{ id: "9",fieldName: "西班牙",fieldTableName: "西班牙",distributors:'UPS',selected: false},
{ id: "10",fieldName: "瑞典",fieldTableName: "瑞典",distributors:'UPS',selected: false},]
},
{ partitionName:'2區(qū)',selected:false,partitionId:2,isIndeterminate:false,
country:[
{ id: "5",fieldName: "丹麥",fieldTableName: "單買",distributors:'',selected: false},
{ id: "6",fieldName: "法國(guó)",fieldTableName: "法國(guó)",distributors:'',selected: false},]
},
{ partitionName:'3區(qū)',selected:false,partitionId:3,isIndeterminate:false,
country:[
{ id: "7",fieldName: "德國(guó)",fieldTableName: "德國(guó)",distributors:'YODEL',selected: false},
{ id: "8",fieldName: "瑞士",fieldTableName: "瑞士",distributors:'DPD',selected: false}]
}
],
ischeckAll:false,//一級(jí)全選狀態(tài)
setDistributorDailog:false,
cancelDistributorDailog:false,
distributorForm:{
vendorName:'',
senderName:''
},
indeterminate:false,
rules: {
senderName: [{ required: true, message: '字段不能為空',trigger: 'blur'}],
website: [{ required: true, message: '字段不能為空',trigger: 'blur'}],
},
}
},
computed: {
},
methods: {
handleCheckAllChange(e){//一級(jí)change事件
this.ischeckAll = e
if(e == true){
this.indeterminate = false
for(var i=0,len=this.distributorsInfo.length; i<len; i++){ //二級(jí)全選反選不確定
this.distributorsInfo[i].selected = e
for(var j=0,len1=this.distributorsInfo[i].country.length; j<len1; j++){
this.distributorsInfo[i].country[j].selected = e
}
}
}else{
this.indeterminate = false
for(var i=0,len=this.distributorsInfo.length; i<len; i++){ //三級(jí)全選反選不確定
this.distributorsInfo[i].selected = e
for(var j=0,len1=this.distributorsInfo[i].country.length; j<len1; j++){
this.distributorsInfo[i].country[j].selected = e
}
}
}
},
handleCheckedCountryAllChange(index, topId, e){//二級(jí)change事件
this.distributorsInfo[index].selected = e//二級(jí)勾選后,子級(jí)全部勾選或者取消
if(e == false) this.distributorsInfo[index].indeterminate = false //去掉二級(jí)不確定狀態(tài)
var childrenArray = this.distributorsInfo[index].country
if(childrenArray)
for(var i=0,len=childrenArray.length; i<len; i++)
childrenArray[i].selected = e
this.getIsCheckAll()
},
handleCheckedCountryChange(topIndex, sonId, topId, e){//三級(jí)change事件
var childrenArray = this.distributorsInfo[topIndex].country
var tickCount = 0, unTickCount = 0, len = childrenArray.length
for(var i = 0; i < len; i++){
if(sonId == childrenArray[i].id) childrenArray[i].selected = e
if(childrenArray[i].selected == true) tickCount++
if(childrenArray[i].selected == false) unTickCount++
}
if(tickCount == len) {//三級(jí)級(jí)全勾選
this.distributorsInfo[topIndex].selected = true
this.distributorsInfo[topIndex].indeterminate = false
} else if(unTickCount == len) {//三級(jí)級(jí)全不勾選
this.distributorsInfo[topIndex].selected = false
this.distributorsInfo[topIndex].indeterminate = false
} else {
this.distributorsInfo[topIndex].selected = false
this.distributorsInfo[topIndex].indeterminate = true //添加二級(jí)不確定狀態(tài)
}
this.getIsCheckAll()
},
getIsCheckAll(){
var tickCount = 0, unTickCount = 0, ArrLength = this.distributorsInfo.length
for(var j=0; j<ArrLength; j++){//全選checkbox狀態(tài)
if(this.distributorsInfo[j].selected == true) tickCount++
if(this.distributorsInfo[j].selected == false) unTickCount++
}
if(tickCount == ArrLength) {//二級(jí)全勾選
this.ischeckAll = true
this.indeterminate = false
} else if(unTickCount == ArrLength) {//二級(jí)全不勾選
this.ischeckAll = false
this.indeterminate = false
} else {
this.ischeckAll = false
this.indeterminate = true //添加一級(jí)不確定狀態(tài)
}
},
showSetDistributorDailog(){
this.setDistributorDailog=true
},
showCancelDistributorDailog(){
this.cancelDistributorDailog=true
}
},
created: function() {
},
mounted: function() {
// (async() => {
},
watch: {
}
}
</script>
<style lang="scss">
.deliverySetting{
padding: 20px 0;
position: relative;
.el-table{
thead{
tr{
th{
font-size: 14px;
}
}
}
tbody{
tr{
td{
vertical-align: baseline;
p{
line-height: 30px;
}
.el-checkbox-group{
display: flex;
flex-direction: column;
label{
line-height: 30px;
margin-left: 0;
}
}
}
}
}
}
.deliverySetting-table{
font-size: 14px;
color: #333;
.table-head,
.table-body{
display: flex;
padding: 10px 0;
.selection{
width: 45px;
text-align: center;
line-height: 36px;
}
.width185{
width: 185px;
}
.width265{
width: 265px;
}
}
.table-head{
height: 36px;
align-items: center;
background-color: #E7F2FF;
}
.table-body{
border-bottom: 1px solid #e4e4e4;
color: #666;
&:hover{
background-color: #f5f7fa;
}
.width265{
display: flex;
flex-direction: column;
label{
line-height: 30px;
margin-left: 0;
color: #666;
}
}
p{
line-height: 30px;
}
}
}
.deliverySetting-btn{
/*width: 100%;*/
height: 59px;
display: flex;
justify-content: flex-end;
align-items: center;
position: absolute;
top: -55px;
right: -16px;
z-index: 100;
.tabs-btn {
min-width: 90px;
height: 34px;
line-height: 32px;
padding: 0 10px;
color: #2387f7;
border: solid 1px #4fa2ff;
background-color: #e7f2ff;
cursor: pointer;
&:nth-of-type(2) {
margin: 0 15px;
}
input {
border: none;
background: transparent;
color: inherit;
cursor: inherit;
outline: none;
margin: 0;
padding: 0;
}
&:hover {
color: #fff;
background-color: #2387f7;
}
}
}
.setDistributorDailog{
.el-input{
width: 270px;
}
}
}
</style>
好了,以后使用三級(jí)甚至多級(jí)復(fù)選都可以使用此方法添加change代碼即可。
總結(jié)
以上所述是小編給大家介紹的vue基于element-ui的三級(jí)CheckBox復(fù)選框功能的實(shí)現(xiàn)代碼,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
- 關(guān)于extjs treepanel復(fù)選框選中父節(jié)點(diǎn)與子節(jié)點(diǎn)的問(wèn)題
- vue+element UI實(shí)現(xiàn)樹形表格帶復(fù)選框的示例代碼
- vuejs+element UI table表格中實(shí)現(xiàn)禁用部分復(fù)選框的方法
- element的el-tree多選樹(復(fù)選框)父子節(jié)點(diǎn)關(guān)聯(lián)不關(guān)聯(lián)
- el-table?選中行與復(fù)選框相互聯(lián)動(dòng)的實(shí)現(xiàn)步驟
- Vue3+ElementUI 多選框中復(fù)選框和名字點(diǎn)擊方法效果分離方法
- 使用element組件table表格實(shí)現(xiàn)某條件下復(fù)選框無(wú)法勾選
- Vue el-table復(fù)選框全部勾選及勾選回顯功能實(shí)現(xiàn)
- el-table表格點(diǎn)擊該行任意位置時(shí)也勾選上其前面的復(fù)選框
相關(guān)文章
Vue解決移動(dòng)端彈窗滾動(dòng)穿透問(wèn)題
這篇文章主要介紹了Vue解決移動(dòng)端彈窗滾動(dòng)穿透問(wèn)題的方法,幫助大家更好的理解和使用vue框架,感興趣的朋友可以了解下2020-12-12
vue2老項(xiàng)目中node-sass更換dart-sass的操作方法
這篇文章主要介紹了vue2老項(xiàng)目中node-sass更換dart-sass的操作方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2024-07-07
Vue3+TS實(shí)現(xiàn)動(dòng)態(tài)路由權(quán)限的示例詳解
當(dāng)我們?cè)陂_發(fā)一個(gè)大型的前端應(yīng)用時(shí),動(dòng)態(tài)路由權(quán)限是一個(gè)必不可少的功能,本文將介紹如何使用Vue 3和TypeScript來(lái)實(shí)現(xiàn)動(dòng)態(tài)路由權(quán)限,希望對(duì)大家有所幫助2024-01-01
Vue3?封裝一個(gè)支持輸入和單/多選InputSelect組件-Antd詳解
Antd的Select組件默認(rèn)不支持作為輸入框使用或手動(dòng)添加選項(xiàng),為了實(shí)現(xiàn)這一功能,我們封裝了一個(gè)通用組件,支持單選和多選模式,并允許用戶在組件失焦時(shí)手動(dòng)輸入選項(xiàng),主要通過(guò)定義searchText存儲(chǔ)輸入數(shù)據(jù),感興趣的朋友跟隨小編一起看看吧2024-09-09
Vue中使用vue-i18插件實(shí)現(xiàn)多語(yǔ)言切換功能
在基于vue-cli項(xiàng)目開發(fā)過(guò)程中,多語(yǔ)言切換功能可使用vue-i18插件,這篇文章分步驟給大家介紹了Vue中使用vue-i18插件實(shí)現(xiàn)多語(yǔ)言切換功能,感興趣的朋友一起看看吧2018-04-04

