vue基于element-ui的三級CheckBox復選框功能的實現(xiàn)代碼
最近vue項目需要用到三級CheckBox復選框,需要實現(xiàn)全選反選不確定三種狀態(tài)。但是element-ui table只支持多選行,并不能支持三級及以上的多選,下面通過本文給大家講解實現(xiàn)方法。
效果圖預覽:
首先是頁面布局,當然也可已使用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">國家</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>
接下來是數(shù)據(jù)結(jié)構(gòu),自定義的,可以更后臺商議,但是字段indeterminate(顯示不確定狀態(tài)~符號),selected(CheckBox選中狀態(tài))一定要讓后臺加入到data中,其他可以按照后臺數(shù)據(jù)來。
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: "法國",fieldTableName: "法國",distributors:'',selected: false},] }, { partitionName:'3區(qū)',selected:false,partitionId:3,isIndeterminate:false, country:[ { id: "7",fieldName: "德國",fieldTableName: "德國",distributors:'YODEL',selected: false}, { id: "8",fieldName: "瑞士",fieldTableName: "瑞士",distributors:'DPD',selected: false}] } ], ischeckAll:false,//一級全選狀態(tài)
因為此處是三級復選,所以函數(shù)為三個change,具體有詳細注釋可以查看
handleCheckAllChange(e){//一級change事件 this.ischeckAll = e if(e == true){ this.indeterminate = false for(var i=0,len=this.distributorsInfo.length; i<len; i++){ //二級全選反選不確定 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++){ //三級全選反選不確定 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){//二級change事件 this.distributorsInfo[index].selected = e//二級勾選后,子級全部勾選或者取消 if(e == false) this.distributorsInfo[index].indeterminate = false //去掉二級不確定狀態(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){//三級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) {//三級級全勾選 this.distributorsInfo[topIndex].selected = true this.distributorsInfo[topIndex].indeterminate = false } else if(unTickCount == len) {//三級級全不勾選 this.distributorsInfo[topIndex].selected = false this.distributorsInfo[topIndex].indeterminate = false } else { this.distributorsInfo[topIndex].selected = false this.distributorsInfo[topIndex].indeterminate = true //添加二級不確定狀態(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) {//二級全勾選 this.ischeckAll = true this.indeterminate = false } else if(unTickCount == ArrLength) {//二級全不勾選 this.ischeckAll = false this.indeterminate = false } else { this.ischeckAll = false this.indeterminate = true //添加一級不確定狀態(tài) } },
以下是頁面完整組件代碼可以使用預覽
<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">國家</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="請輸入供應商名稱"></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="請選派送商名稱"> <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="請輸入派送商官網(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">您確定要取消對的派送分配嗎?</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: "法國",fieldTableName: "法國",distributors:'',selected: false},] }, { partitionName:'3區(qū)',selected:false,partitionId:3,isIndeterminate:false, country:[ { id: "7",fieldName: "德國",fieldTableName: "德國",distributors:'YODEL',selected: false}, { id: "8",fieldName: "瑞士",fieldTableName: "瑞士",distributors:'DPD',selected: false}] } ], ischeckAll:false,//一級全選狀態(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){//一級change事件 this.ischeckAll = e if(e == true){ this.indeterminate = false for(var i=0,len=this.distributorsInfo.length; i<len; i++){ //二級全選反選不確定 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++){ //三級全選反選不確定 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){//二級change事件 this.distributorsInfo[index].selected = e//二級勾選后,子級全部勾選或者取消 if(e == false) this.distributorsInfo[index].indeterminate = false //去掉二級不確定狀態(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){//三級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) {//三級級全勾選 this.distributorsInfo[topIndex].selected = true this.distributorsInfo[topIndex].indeterminate = false } else if(unTickCount == len) {//三級級全不勾選 this.distributorsInfo[topIndex].selected = false this.distributorsInfo[topIndex].indeterminate = false } else { this.distributorsInfo[topIndex].selected = false this.distributorsInfo[topIndex].indeterminate = true //添加二級不確定狀態(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) {//二級全勾選 this.ischeckAll = true this.indeterminate = false } else if(unTickCount == ArrLength) {//二級全不勾選 this.ischeckAll = false this.indeterminate = false } else { this.ischeckAll = false this.indeterminate = true //添加一級不確定狀態(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>
好了,以后使用三級甚至多級復選都可以使用此方法添加change代碼即可。
總結(jié)
以上所述是小編給大家介紹的vue基于element-ui的三級CheckBox復選框功能的實現(xiàn)代碼,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
- 關(guān)于extjs treepanel復選框選中父節(jié)點與子節(jié)點的問題
- vue+element UI實現(xiàn)樹形表格帶復選框的示例代碼
- vuejs+element UI table表格中實現(xiàn)禁用部分復選框的方法
- element的el-tree多選樹(復選框)父子節(jié)點關(guān)聯(lián)不關(guān)聯(lián)
- el-table?選中行與復選框相互聯(lián)動的實現(xiàn)步驟
- Vue3+ElementUI 多選框中復選框和名字點擊方法效果分離方法
- 使用element組件table表格實現(xiàn)某條件下復選框無法勾選
- Vue el-table復選框全部勾選及勾選回顯功能實現(xiàn)
- el-table表格點擊該行任意位置時也勾選上其前面的復選框
相關(guān)文章
vue2老項目中node-sass更換dart-sass的操作方法
這篇文章主要介紹了vue2老項目中node-sass更換dart-sass的操作方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2024-07-07Vue3+TS實現(xiàn)動態(tài)路由權(quán)限的示例詳解
當我們在開發(fā)一個大型的前端應用時,動態(tài)路由權(quán)限是一個必不可少的功能,本文將介紹如何使用Vue 3和TypeScript來實現(xiàn)動態(tài)路由權(quán)限,希望對大家有所幫助2024-01-01Vue3?封裝一個支持輸入和單/多選InputSelect組件-Antd詳解
Antd的Select組件默認不支持作為輸入框使用或手動添加選項,為了實現(xiàn)這一功能,我們封裝了一個通用組件,支持單選和多選模式,并允許用戶在組件失焦時手動輸入選項,主要通過定義searchText存儲輸入數(shù)據(jù),感興趣的朋友跟隨小編一起看看吧2024-09-09Vue中使用vue-i18插件實現(xiàn)多語言切換功能
在基于vue-cli項目開發(fā)過程中,多語言切換功能可使用vue-i18插件,這篇文章分步驟給大家介紹了Vue中使用vue-i18插件實現(xiàn)多語言切換功能,感興趣的朋友一起看看吧2018-04-04