vue基于element-ui的三级CheckBox复选框

最近vue项目需要用到三级CheckBox复选框,需要实现全选反选不确定三种状态。但是element-ui table只支持多选行,并不能支持三级及以上的多选,所以写了这篇博客以后学习使用。

效果图预览:

首先是页面布局,当然也可已使用table,但是自己用flex布局后面更容易增删改查其他功能

 1 <div class="deliverySetting-table">
 2             <div class="table-head">
 3                 <div class="selection">
 4                     <el-checkbox :indeterminate="indeterminate" v-model="ischeckAll" @change="handleCheckAllChange"></el-checkbox>
 5                 </div>
 6                 <div class="width185">分区名称</div>
 7                 <div class="width265">国家</div>
 8                 <div>派送商</div>
 9             </div>
10             <div class="table-body" v-for="(partition,partitionIndex) in distributorsInfo" :key="partitionIndex">
11                 <div class="selection">
12                     <p><el-checkbox :indeterminate="partition.indeterminate" v-model="partition.selected" @change="handleCheckedCountryAllChange(partitionIndex,partition.partitionId,$event)" :key="partitionIndex"></el-checkbox></p>
13                 </div>
14                 <div class="width185"><p>{{ partition.partitionName }}</p></div>
15                 <div class="width265">
16                     <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>
17                 </div>
18                 <div>
19                     <p v-for="(item,index) in partition.country" :key="index">
20                         {{ item.distributors }}
21                     </p>
22                 </div>
23             </div>
24         </div>

接下来是数据结构,自定义的,可以更后台商议,但是字段indeterminate(显示不确定状态~符号),selected(CheckBox选中状态)一定要让后台加入到data中,其他可以按照后台数据来。

 2                 distributorsInfo:[
 3                     { partitionName:'1区',selected:false,partitionId:1,isIndeterminate:false,
 4                         country:[
 5                         {   id: "1",fieldName: "奥地利",fieldTableName: "奥地利",distributors:'UPS',selected: false},
 6                         {   id: "2",fieldName: "芬兰",fieldTableName: "芬兰",distributors:'UPS',selected: false},
 7                         {   id: "3",fieldName: "意大利",fieldTableName: "意大利",distributors:'UPS',selected: false},
 8                         {   id: "4",fieldName: "葡萄牙",fieldTableName: "葡萄牙",distributors:'UPS',selected: false},
 9                         {   id: "9",fieldName: "西班牙",fieldTableName: "西班牙",distributors:'UPS',selected: false},
10                         {   id: "10",fieldName: "瑞典",fieldTableName: "瑞典",distributors:'UPS',selected: false},]
11                     },
12                     { partitionName:'2区',selected:false,partitionId:2,isIndeterminate:false,
13                         country:[
14                         {   id: "5",fieldName: "丹麦",fieldTableName: "单买",distributors:'',selected: false},
15                         {   id: "6",fieldName: "法国",fieldTableName: "法国",distributors:'',selected: false},]
16                     },
17                     { partitionName:'3区',selected:false,partitionId:3,isIndeterminate:false,
18                         country:[
19                         {   id: "7",fieldName: "德国",fieldTableName: "德国",distributors:'YODEL',selected: false},
20                         {   id: "8",fieldName: "瑞士",fieldTableName: "瑞士",distributors:'DPD',selected: false}]
21                     }
22                 ],
23                 ischeckAll:false,//一级全选状态

因为此处是三级复选,所以函数为三个change,具体有详细注释可以查看

 1  handleCheckAllChange(e){//一级change事件
 2                 this.ischeckAll = e
 3                 if(e == true){
 4                     this.indeterminate = false
 5                     for(var i=0,len=this.distributorsInfo.length; i<len; i++){ //二级全选反选不确定
 6                         this.distributorsInfo[i].selected = e
 7                         for(var j=0,len1=this.distributorsInfo[i].country.length; j<len1; j++){
 8                             this.distributorsInfo[i].country[j].selected = e
 9                         }
10                     }
11                 }else{
12                     this.indeterminate = false
13                     for(var i=0,len=this.distributorsInfo.length; i<len; i++){ //三级全选反选不确定
14                         this.distributorsInfo[i].selected = e
15                         for(var j=0,len1=this.distributorsInfo[i].country.length; j<len1; j++){
16                             this.distributorsInfo[i].country[j].selected = e
17                         }
18                     }
19                 }
20             },
21             handleCheckedCountryAllChange(index, topId, e){//二级change事件
22                 this.distributorsInfo[index].selected = e//二级勾选后,子级全部勾选或者取消
23                 if(e == false) this.distributorsInfo[index].indeterminate = false //去掉二级不确定状态
24                 var childrenArray = this.distributorsInfo[index].country
25                 if(childrenArray)
26                     for(var i=0,len=childrenArray.length; i<len; i++)
27                         childrenArray[i].selected = e
28 
29                 this.getIsCheckAll()
30             },
31             handleCheckedCountryChange(topIndex, sonId, topId, e){//三级change事件
32                 var childrenArray = this.distributorsInfo[topIndex].country
33                 var tickCount = 0, unTickCount = 0, len = childrenArray.length
34                 for(var i = 0; i < len; i++){
35                     if(sonId == childrenArray[i].id) childrenArray[i].selected = e
36                     if(childrenArray[i].selected == true) tickCount++
37                     if(childrenArray[i].selected == false) unTickCount++
38                 }
39                 if(tickCount == len) {//三级级全勾选
40                     this.distributorsInfo[topIndex].selected = true 
41                     this.distributorsInfo[topIndex].indeterminate = false
42                 } else if(unTickCount == len) {//三级级全不勾选
43                     this.distributorsInfo[topIndex].selected = false 
44                     this.distributorsInfo[topIndex].indeterminate = false
45                 } else {
46                     this.distributorsInfo[topIndex].selected = false
47                     this.distributorsInfo[topIndex].indeterminate = true //添加二级不确定状态
48                 }
49 
50                 this.getIsCheckAll()
51             },
52             getIsCheckAll(){
53                 var tickCount = 0, unTickCount = 0, ArrLength = this.distributorsInfo.length
54                 for(var j=0; j<ArrLength; j++){//全选checkbox状态
55                     if(this.distributorsInfo[j].selected == true) tickCount++
56                     if(this.distributorsInfo[j].selected == false) unTickCount++
57                 }
58                 if(tickCount == ArrLength) {//二级全勾选
59                     this.ischeckAll = true
60                     this.indeterminate = false
61                 } else if(unTickCount == ArrLength) {//二级全不勾选
62                     this.ischeckAll = false
63                     this.indeterminate = false
64                 } else {
65                     this.ischeckAll = false
66                     this.indeterminate = true //添加一级不确定状态
67                 }
68             },

以下是页面完整组件代码可以使用预览

  1 <template>
  2     <div class="deliverySetting">
  3         <div class="deliverySetting-btn">
  4             <div class="tabs-btn ac">
  5                 <input type="button" value="分配派送商" @click="showSetDistributorDailog">
  6             </div>
  7             <div class="tabs-btn ac">
  8                 <input type="button" value="取消分配" @click="showCancelDistributorDailog">
  9             </div>
 10         </div>
 11 
 12         <div class="deliverySetting-table">
 13             <div class="table-head">
 14                 <div class="selection">
 15                     <el-checkbox :indeterminate="indeterminate" v-model="ischeckAll" @change="handleCheckAllChange"></el-checkbox>
 16                 </div>
 17                 <div class="width185">分区名称</div>
 18                 <div class="width265">国家</div>
 19                 <div>派送商</div>
 20             </div>
 21             <div class="table-body" v-for="(partition,partitionIndex) in distributorsInfo" :key="partitionIndex">
 22                 <div class="selection">
 23                     <p><el-checkbox :indeterminate="partition.indeterminate" v-model="partition.selected" @change="handleCheckedCountryAllChange(partitionIndex,partition.partitionId,$event)" :key="partitionIndex"></el-checkbox></p>
 24                 </div>
 25                 <div class="width185"><p>{{ partition.partitionName }}</p></div>
 26                 <div class="width265">
 27                     <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>
 28                 </div>
 29                 <div>
 30                     <p v-for="(item,index) in partition.country" :key="index">
 31                         {{ item.distributors }}
 32                     </p>
 33                 </div>
 34             </div>
 35         </div>
 36 
 37         <!-- 分配派送商dailog -->
 38         <el-dialog title="分配派送商" :visible.sync="setDistributorDailog" width="480px">
 39             <el-form :model="distributorForm" :rules="rules" class="setDistributorDailog">
 40                 <el-form-item label="派送代理商" label-width="120px">
 41                     <el-input v-model="distributorForm.vendorName" auto-complete="off" placeholder="请输入供应商名称"></el-input>
 42                 </el-form-item>
 43                 <el-form-item label="末端派送商" prop="senderName" label-width="120px">
 44                     <el-select v-model="distributorForm.senderName"
 45                     filterable
 46                     allow-create
 47                     default-first-option
 48                     placeholder="请选派送商名称">
 49                         <el-option label="派送商1" value="shanghai"></el-option>
 50                         <el-option label="派送商2" value="beijing"></el-option>
 51                     </el-select>
 52                 </el-form-item>
 53                 <el-form-item label="派送商官网" prop="website" label-width="120px">
 54                     <el-input v-model="distributorForm.website" auto-complete="off" placeholder="请输入派送商官网"></el-input>
 55                 </el-form-item>
 56             </el-form>
 57             <div slot="footer" class="dialog-footer">
 58                 <el-button @click="setDistributorDailog = false">取 消</el-button>
 59                 <el-button type="primary" @click="setDistributorDailog = false">确 定</el-button>
 60             </div>
 61         </el-dialog>
 62 
 63         <!-- 取消分配派送商 -->
 64         <el-dialog title="停止提示" :visible.sync="cancelDistributorDailog" :modal="false" width="480px" custom-class="stop-coupon-dialog">
 65             <p><br></p>
 66             <p class="ac f16">您确定要取消对的派送分配吗?</p>
 67             <p><br></p>
 68             <span slot="footer" class="dialog-footer">
 69                 <el-button @click="cancelDistributorDailog = false">取 消</el-button>
 70                 <el-button type="primary" @click="cancelDistributorDailog=false">确 定</el-button>
 71             </span>
 72         </el-dialog>
 73     </div>
 74 </template>
 75 <script>
 76     export default {
 77         name:'deliverySetting',
 78         components: {
 79         },
 80         props:{
 81         },
 82         data() {
 83             return {
 84                 distributorsInfo:[
 85                     { partitionName:'1区',selected:false,partitionId:1,isIndeterminate:false,
 86                         country:[
 87                         {   id: "1",fieldName: "奥地利",fieldTableName: "奥地利",distributors:'UPS',selected: false},
 88                         {   id: "2",fieldName: "芬兰",fieldTableName: "芬兰",distributors:'UPS',selected: false},
 89                         {   id: "3",fieldName: "意大利",fieldTableName: "意大利",distributors:'UPS',selected: false},
 90                         {   id: "4",fieldName: "葡萄牙",fieldTableName: "葡萄牙",distributors:'UPS',selected: false},
 91                         {   id: "9",fieldName: "西班牙",fieldTableName: "西班牙",distributors:'UPS',selected: false},
 92                         {   id: "10",fieldName: "瑞典",fieldTableName: "瑞典",distributors:'UPS',selected: false},]
 93                     },
 94                     { partitionName:'2区',selected:false,partitionId:2,isIndeterminate:false,
 95                         country:[
 96                         {   id: "5",fieldName: "丹麦",fieldTableName: "单买",distributors:'',selected: false},
 97                         {   id: "6",fieldName: "法国",fieldTableName: "法国",distributors:'',selected: false},]
 98                     },
 99                     { partitionName:'3区',selected:false,partitionId:3,isIndeterminate:false,
100                         country:[
101                         {   id: "7",fieldName: "德国",fieldTableName: "德国",distributors:'YODEL',selected: false},
102                         {   id: "8",fieldName: "瑞士",fieldTableName: "瑞士",distributors:'DPD',selected: false}]
103                     }
104                 ],
105                 ischeckAll:false,//一级全选状态
106                 setDistributorDailog:false,
107                 cancelDistributorDailog:false,
108                 distributorForm:{
109                     vendorName:'',
110                     senderName:''
111                 },
112                 indeterminate:false,
113                 rules: {
114                     senderName: [{ required: true, message: '字段不能为空',trigger: 'blur'}],
115                     website: [{ required: true, message: '字段不能为空',trigger: 'blur'}],
116                 },
117             }
118         },
119         computed: {
120         },
121         methods: {
122             handleCheckAllChange(e){//一级change事件
123                 this.ischeckAll = e
124                 if(e == true){
125                     this.indeterminate = false
126                     for(var i=0,len=this.distributorsInfo.length; i<len; i++){ //二级全选反选不确定
127                         this.distributorsInfo[i].selected = e
128                         for(var j=0,len1=this.distributorsInfo[i].country.length; j<len1; j++){
129                             this.distributorsInfo[i].country[j].selected = e
130                         }
131                     }
132                 }else{
133                     this.indeterminate = false
134                     for(var i=0,len=this.distributorsInfo.length; i<len; i++){ //三级全选反选不确定
135                         this.distributorsInfo[i].selected = e
136                         for(var j=0,len1=this.distributorsInfo[i].country.length; j<len1; j++){
137                             this.distributorsInfo[i].country[j].selected = e
138                         }
139                     }
140                 }
141             },
142             handleCheckedCountryAllChange(index, topId, e){//二级change事件
143                 this.distributorsInfo[index].selected = e//二级勾选后,子级全部勾选或者取消
144                 if(e == false) this.distributorsInfo[index].indeterminate = false //去掉二级不确定状态
145                 var childrenArray = this.distributorsInfo[index].country
146                 if(childrenArray)
147                     for(var i=0,len=childrenArray.length; i<len; i++)
148                         childrenArray[i].selected = e
149 
150                 this.getIsCheckAll()
151             },
152             handleCheckedCountryChange(topIndex, sonId, topId, e){//三级change事件
153                 var childrenArray = this.distributorsInfo[topIndex].country
154                 var tickCount = 0, unTickCount = 0, len = childrenArray.length
155                 for(var i = 0; i < len; i++){
156                     if(sonId == childrenArray[i].id) childrenArray[i].selected = e
157                     if(childrenArray[i].selected == true) tickCount++
158                     if(childrenArray[i].selected == false) unTickCount++
159                 }
160                 if(tickCount == len) {//三级级全勾选
161                     this.distributorsInfo[topIndex].selected = true 
162                     this.distributorsInfo[topIndex].indeterminate = false
163                 } else if(unTickCount == len) {//三级级全不勾选
164                     this.distributorsInfo[topIndex].selected = false 
165                     this.distributorsInfo[topIndex].indeterminate = false
166                 } else {
167                     this.distributorsInfo[topIndex].selected = false
168                     this.distributorsInfo[topIndex].indeterminate = true //添加二级不确定状态
169                 }
170 
171                 this.getIsCheckAll()
172             },
173             getIsCheckAll(){
174                 var tickCount = 0, unTickCount = 0, ArrLength = this.distributorsInfo.length
175                 for(var j=0; j<ArrLength; j++){//全选checkbox状态
176                     if(this.distributorsInfo[j].selected == true) tickCount++
177                     if(this.distributorsInfo[j].selected == false) unTickCount++
178                 }
179                 if(tickCount == ArrLength) {//二级全勾选
180                     this.ischeckAll = true
181                     this.indeterminate = false
182                 } else if(unTickCount == ArrLength) {//二级全不勾选
183                     this.ischeckAll = false
184                     this.indeterminate = false
185                 } else {
186                     this.ischeckAll = false
187                     this.indeterminate = true //添加一级不确定状态
188                 }
189             },
190 
191             showSetDistributorDailog(){
192                 this.setDistributorDailog=true
193             },
194             showCancelDistributorDailog(){
195                 this.cancelDistributorDailog=true
196             }
197         },
198         created: function() {
199         },
200         mounted: function() {
201             // (async() => {
202         },
203         watch: {
204         }
205     }
206 </script>
207 <style lang="scss">
208 .deliverySetting{
209     padding: 20px 0;
210     position: relative;
211     .el-table{
212         thead{
213             tr{
214                 th{
215                     font-size: 14px;
216                 }
217             }
218         }
219         tbody{
220             tr{
221                 td{
222                     vertical-align: baseline;
223                     p{
224                         line-height: 30px;
225                     }
226                     .el-checkbox-group{
227                         display: flex;
228                         flex-direction: column;
229                         label{
230                             line-height: 30px;
231                             margin-left: 0;
232                         }
233                     }
234                 }
235             }
236         }
237     }
238     .deliverySetting-table{
239         font-size: 14px;
240         color: #333;
241         .table-head,
242         .table-body{
243             display: flex;
244             padding: 10px 0;
245             .selection{
246                 width: 45px;
247                 text-align: center;
248                 line-height: 36px;
249             }
250             .width185{
251                 width: 185px;
252             }
253             .width265{
254                 width: 265px;
255             }
256         }
257         .table-head{
258             height: 36px;
259             align-items: center;
260             background-color: #E7F2FF;
261         }
262         .table-body{
263             border-bottom: 1px solid #e4e4e4;
264             color: #666;
265             &:hover{
266                 background-color: #f5f7fa;
267             }
268             .width265{
269                 display: flex;
270                 flex-direction: column;
271                 label{
272                     line-height: 30px;
273                     margin-left: 0;
274                     color: #666;
275                 }
276             }
277             p{
278                 line-height: 30px;
279             }
280         }
281     }
282     .deliverySetting-btn{
283         /*width: 100%;*/
284         height: 59px;
285         display: flex;
286         justify-content: flex-end;
287         align-items: center;
288         position: absolute;
289         top: -55px;
290         right: -16px;
291         z-index: 100;
292         .tabs-btn {
293             min-width: 90px;
294             height: 34px;
295             line-height: 32px;
296             padding: 0 10px;
297             color: #2387f7;
298             border: solid 1px #4fa2ff;
299             background-color: #e7f2ff;
300             cursor: pointer;
301             &:nth-of-type(2) {
302                 margin: 0 15px;
303             }
304             input {
305                 border: none;
306                 background: transparent;
307                 color: inherit;
308                 cursor: inherit;
309                 outline: none;
310                 margin: 0;
311                 padding: 0;
312             }
313             &:hover {
314                 color: #fff;
315                 background-color: #2387f7;
316             }
317         }
318     }
319     .setDistributorDailog{
320         .el-input{
321             width: 270px;
322         }
323     }
324 }
325 </style>
View Code

好了,以后使用三级甚至多级复选都可以使用此方法添加change代码即可。

猜你喜欢

转载自www.cnblogs.com/wangmingcong/p/9781775.html
今日推荐