日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

树形选择变成表格树选择

發(fā)布時(shí)間:2024/1/1 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 树形选择变成表格树选择 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

需求:在接口不改動(dòng)的情況下由樹(shù)形結(jié)構(gòu)改成表格樹(shù)結(jié)構(gòu),如下圖

原圖

調(diào)整后

1.這里使用的是antdesign框架,首先將a-tree改為a-table

<!-- <a-tree checkable v-model="checkedKeys" :treeData="menuTree" @check="checkItem"></a-tree> --><a-table :columns="columns" :data-source="data" :pagination="false"></a-table>

2.定義table中的columns

// 這里除了第一列是菜單名稱以外,其余都是checkbox,checkbox采用插槽的方式實(shí)現(xiàn) /*** slots里面定義的是頭部插槽名字,頭部也有一個(gè)多選框* scopedSlots定義的是當(dāng)前列插槽的名字* */ columns: [{title: '授權(quán)菜單',dataIndex: 'title',key: 'title' },{dataIndex: 'entry',key: 'entry',align:'center',slots: { title: 'customEntry' },scopedSlots: { customRender: 'checkBoxEntry' }},{dataIndex: 'edit',align:'center',key: 'edit',slots: { title: 'customEdit' },scopedSlots: { customRender: 'checkBoxEdit' }},{dataIndex: 'approval',align:'center',key: 'approval',slots: { title: 'customApproval' },scopedSlots: { customRender: 'checkBoxApproval' }},{dataIndex: 'query',align:'center',key: 'query',slots: { title: 'customQuery' },scopedSlots: { customRender: 'checkBoxQuery' }}],

此時(shí)在table中加入checkbox插槽

// 例如頭部 <a-checkbox slot="customEntry">錄入</a-checkbox> <a-checkbox slot="customEdit">編輯</a-checkbox> <a-checkbox slot="customApproval">審核</a-checkbox> <a-checkbox slot="customQuery">查詢</a-checkbox> // 每一列同理 <a-checkbox slot="checkBoxEntry" slot-scope="text,item"></a-checkbox>

3.修改后端返回?cái)?shù)據(jù)data,由于之前是根據(jù)樹(shù)形結(jié)構(gòu)顯示,后端在返回?cái)?shù)據(jù)之前已經(jīng)很友好的把數(shù)據(jù)封裝成樹(shù)形結(jié)構(gòu),示例如下:
(其中a10001、a10002、a10003、a10004分別表示錄入、編輯、審核、查詢權(quán)限)

[{ //一級(jí)菜單"title": "計(jì)劃管理", "children": [{ // 授權(quán)模塊"menuCode": "15","title": "設(shè)備需求計(jì)劃", "children": [{ // 模塊可分配的權(quán)限"authority_button_name": "錄入","authority_button_code": "a10001","menu_id": "15"},{"authority_button_name": "編輯","authority_button_code": "a10002","menu_id": "15"},{"authority_button_name": "審核","authority_button_code": "a10003","menu_id": "15"},{"authority_button_name": "查詢","authority_button_code": "a10004","menu_id": "15"}],}],"menuCode": "14"},{"title": "設(shè)備進(jìn)場(chǎng)管理","children": [{"title": "設(shè)備進(jìn)場(chǎng)驗(yàn)收管理","children": [{"authority_button_name": "錄入","authority_button_code": "a10001","menu_id": "33"}],"menuCode": "33"},{"title": "水電管理","children": [{ // 二級(jí)菜單"title": "水電抄表記錄單","children": [{"authority_button_name": "錄入","authority_button_code": "a10001","menu_id": "40"},{"authority_button_name": "編輯","authority_button_code": "a10002","menu_id": "40"},{"authority_button_name": "審核","authority_button_code": "a10003","menu_id": "40"},{"authority_button_name": "查詢","authority_button_code": "a10004","menu_id": "40"}],"menuCode": "40"}],"menuCode": "112"}],"menuCode": "38"},],

由于樹(shù)形結(jié)構(gòu)的數(shù)據(jù)與表格樹(shù)的數(shù)據(jù)基本類型,因此只需要把最里面一層children(模塊可分配的權(quán)限)拿出來(lái)即可。

處理完以后的數(shù)據(jù)結(jié)構(gòu)如下:

  • authButtonGroup保存該模塊下可選擇的權(quán)限,即原始數(shù)據(jù)中的children中的數(shù)據(jù),刪除該children字段
  • authButton保存該用戶在該模塊下已經(jīng)存在的權(quán)限
  • [{ //一級(jí)菜單"title": "計(jì)劃管理", "children": [{ // 授權(quán)模塊"menuCode": "15","title": "設(shè)備需求計(jì)劃", authButtonGroup: ['a10001','a10002','a10003','a10004'], // 授權(quán)模塊可選的權(quán)限authButton: ['a10001'] // 該用戶目前已經(jīng)擁有的權(quán)限}],"menuCode": "14"},{"title": "設(shè)備進(jìn)場(chǎng)管理","children": [{"title": "設(shè)備進(jìn)場(chǎng)驗(yàn)收管理",authButtonGroup: ['a10001'],authButton: ['a10001'],"menuCode": "33" },{"title": "水電管理","children": [{ // 二級(jí)菜單"title": "水電抄表記錄單",authButtonGroup: ['a10001','a10002','a10003','a10004'],authButton: ['a10001'] "menuCode": "40"}],"menuCode": "112"}],"menuCode": "38"},],

    處理數(shù)據(jù)的方法如下:

    let promises = [獲取用戶權(quán)限的接口,獲取權(quán)限樹(shù)的接口];Promise.all(promises).then(result=>{// 對(duì)用戶權(quán)限做處理,用授權(quán)模塊的menu_code作為key存入對(duì)象,以便下面使用let authButton = result[0].responseList;let authButtonMap = {};Array.isArray(authButton) && authButton.forEach(item=>{authButtonMap[item.menu_code] = item.authority_button_codes ? item.authority_button_codes.split(',') : [];})// 獲取到權(quán)限樹(shù)let data = [...result[1].responseList];// 定義一個(gè)方法對(duì)樹(shù)進(jìn)行處理function dealTree(item){let child = item.children;// 子節(jié)點(diǎn)不是菜單就是權(quán)限按鈕,一般子節(jié)點(diǎn)下都只存在一種類型,非1即2child.forEach(inner=>{// 通過(guò)title判斷,沒(méi)有的就是模塊可選的權(quán)限if(inner.title){dealTree(inner)}else{// 是模塊可選的權(quán)限了,存起來(lái)!item.authButtonGroup && (item.authButtonGroup = []);item.authButtonGroup.push(inner.authority_button_code);}})if(item.authButtonGroup){item.authButton = authButtonMap[item.menuCode] || []; // 存儲(chǔ)用戶在當(dāng)前模塊已有的權(quán)限delete item.children; // 刪除children}return item;}this.data = data.map(item=>{return dealTree(item);});

    此時(shí)數(shù)據(jù)結(jié)構(gòu)就變成了

    菜單授權(quán)模塊(包含模塊可選的權(quán)限)菜單授權(quán)模塊(包含模塊可選的權(quán)限)

    下面給checkbox綁定屬性(點(diǎn)擊事件、默認(rèn)選中、菜單的半選狀態(tài))

    先根據(jù)用戶存在的權(quán)限默認(rèn)選中:

    // 如何當(dāng)前授權(quán)模塊中的authButton有a10001說(shuō)明該用戶存在這個(gè)權(quán)限,設(shè)置選中 <a-checkbox slot="checkBoxEntry" slot-scope="text,item" :checked="item.authButton.includes('a10001')"></a-checkbox>

    分析:
    1.當(dāng)該節(jié)點(diǎn)是菜單時(shí),不存在authButton這個(gè)數(shù)組
    2.checkbox是否顯示應(yīng)該根據(jù)authButtonGroup這個(gè)數(shù)組中是否有值,即該模塊可以被授什么權(quán)

    進(jìn)行如下改造:

    <template slot="checkBoxEntry" slot-scope="text,item">// 該節(jié)點(diǎn)存在authButtonGroup,即授權(quán)模塊<template v-if="item.authButtonGroup">// 判斷該模塊是否可以授權(quán)a10001,即authButtonGroup是否存在,有就顯示checkbox,沒(méi)有就不顯示<a-checkbox v-if="item.authButtonGroup.includes('a10001')" :checked="item.authButton.includes('a10001')"></a-checkbox><span v-else></span></template>// 菜單是否顯示checkbox,// 菜單顯示checkbox的用途是用于給下面所有模塊的全選或者全取消功能// 所有應(yīng)該判斷下面的模塊是否存在checkbox,這里的判讀條件不夠全面,下面再說(shuō)<a-checkbox v-else-if="item.children.some(inner => inner.authButtonGroup.includes('a10001'))" ></a-checkbox><span v-else></span> </template>

    綁定點(diǎn)擊事件
    (由于每個(gè)checkbox設(shè)置的選中狀態(tài)都是通過(guò)該模塊的authButton數(shù)組是否有a10001、a10002、a10003、a10004。因此原理就是在該授權(quán)模塊的authButton將指定的authCode加入或者刪除)

    <template slot="checkBoxEntry" slot-scope="text,item"><template v-if="item.authButtonGroup"><a-checkbox@change="onChangeRecord($event,item,'a10001')" v-if="item.authButtonGroup.includes('a10001')" :checked="item.authButton.includes('a10001')"></a-checkbox><span v-else></span></template><a-checkbox@change="onChangeRecordMenu($event,item,'a10001')"v-else-if="item.children.some(inner => inner.authButtonGroup.includes('a10001'))"></a-checkbox><span v-else></span> </template>/** 授權(quán)模塊的點(diǎn)擊事件 **/ onChangeRecord(event,record,authCode){this.compareDleteOrAdd(record.authButton,authCode,true,true); // 之前是選中點(diǎn)擊即刪除,之前未選中點(diǎn)擊即添加this.$forceUpdate(); // 由于綁定的都是方法執(zhí)行結(jié)果,手動(dòng)觸發(fā)視圖更新 }, // 在數(shù)組中增加或者減少一項(xiàng) compareDleteOrAdd(arr,item,isAdd,isDel){let index = arr.indexOf(item)if(index > -1){if(isDel){arr.splice(index,1);}}else{if(isAdd){arr.push(item);}}return index; }, /** 菜單的點(diǎn)擊事件 **/ onChangeRecordMenu(event,record,authCode){// 先獲取當(dāng)前點(diǎn)擊按鈕是選中還是取消,選中即菜單下所有模塊全部選中,相反取消則全部取消let flag = event.target.checked;// 獲取菜單下面的授權(quán)模塊或者下級(jí)菜單let children = record.children;let stack = [];// 循環(huán)遍歷,將所有的子模塊都添加或者刪除authCodewhile(children){children.forEach(item=>{// 是授權(quán)模塊則直接刪除或添加if(item.authButtonGroup){if(item.authButtonGroup.includes(authCode)){if(flag){this.compareDleteOrAdd(item.authButton,authCode,true,false);}else{this.compareDleteOrAdd(item.authButton,authCode,false,true);}}}else{// 如果是菜單,定義一個(gè)stack棧存入,下級(jí)菜單中的授權(quán)模塊也需要處理stack.push(item);}})// 將stack棧中的菜單從第一個(gè)推出,再循環(huán)(主要是存在多級(jí)菜單的原因)let next = stack.shift();children = next ? next.children : '';}this.$forceUpdate(); // 手動(dòng)觸發(fā)視圖更新 },

    設(shè)置菜單的選中、半選狀態(tài)

    <template slot="checkBoxEntry" slot-scope="text,item"><template v-if="item.authButtonGroup"><a-checkbox@change="onChangeRecord($event,item,'a10001')" v-if="item.authButtonGroup.includes('a10001')" :checked="item.authButton.includes('a10001')"></a-checkbox><span v-else></span></template><a-checkbox@change="onChangeRecordMenu($event,item,'a10001')"v-else-if="item.children.some(inner => inner.authButtonGroup.includes('a10001'))":checked="checkAllSelect(item,'a10001')":indeterminate="indeterminateCheck(item,'a10001') && !checkAllSelect(item,'a10001')" ></a-checkbox><span v-else></span> </template>/** 菜單的全選狀態(tài)checkAllSelect返回true即全選 **/ // 即只需找到一個(gè)授權(quán)模塊沒(méi)有選中即返回false,找不到返回true checkAllSelect(item,authCode){// 找到一個(gè)不滿足let flag = true;let children = item.children;if(!item || !item.children){return false;}let stack = [];while(children){children.some(item=>{if(item.authButtonGroup){if(item.authButtonGroup.includes(authCode)){flag = item.authButton.includes(authCode);return !flag;}}else{stack.push(item);return false;}})// 找到了不向下執(zhí)行if(!flag){break;}let next = stack.shift();children = next ? next.children : '';}return flag; },/** 菜單的半選狀態(tài)設(shè)置checkout的indeterminate屬性為true,即半選**/ // 半選其實(shí)就是至少有一個(gè)選中并且不是全部選中 // :indeterminate="indeterminateCheck(item,'a10001') && !checkAllSelect(item,'a10001')" // 找到至少一個(gè)選中 indeterminateCheck(item,authCode){// 至少有一個(gè)選中l(wèi)et flag = false;let children = item.children;let stack = [];while(children){children.some(item=>{if(item.authButtonGroup){if(item.authButtonGroup.includes(authCode)){flag = item.authButton.includes(authCode);return flag;}}else{stack.push(item);return false;}})// 找到了有一個(gè)if(flag){break;}let next = stack.shift();children = next ? next.children : '';}return flag; },

    完成以上操作基本上菜單的全選、取消、半選狀態(tài),授權(quán)模塊的選擇取消都已經(jīng)處理完了

    處理頂部的全選按鈕(其實(shí)方法都是執(zhí)行一樣的,只是傳參數(shù)的時(shí)候?qū)⑦@個(gè)表格數(shù)據(jù)data當(dāng)初children傳人即可)

    <a-checkbox @change="onChangeAll($event,'a10001')" :checked="checkAllSelect({children:data},'a10001')":indeterminate="indeterminateCheck({children:data},'a10001') && !checkAllSelect({children:data},'a10001')"slot="customEntry">錄入</a-checkbox>/** 點(diǎn)擊事件 **/ onChangeAll(event,authCode){this.onChangeRecordMenu(event,{children:this.data},authCode); },

    完整代碼如下:

    <template><div class="permission-auth-model"><a-table :columns="columns" :data-source="data" :pagination="false"><a-checkbox @change="onChangeAll($event,'a10001')" :checked="checkAllSelect({children:data},'a10001')":indeterminate="indeterminateCheck({children:data},'a10001') && !checkAllSelect({children:data},'a10001')"slot="customEntry">錄入</a-checkbox><a-checkbox @change="onChangeAll($event,'a10002')" :checked="checkAllSelect({children:data},'a10002')":indeterminate="indeterminateCheck({children:data},'a10002') && !checkAllSelect({children:data},'a10002')"slot="customEdit">編輯</a-checkbox><a-checkbox @change="onChangeAll($event,'a10003')":checked="checkAllSelect({children:data},'a10003')":indeterminate="indeterminateCheck({children:data},'a10003') && !checkAllSelect({children:data},'a10003')" slot="customApproval">審核</a-checkbox><a-checkbox @change="onChangeAll($event,'a10004')":checked="checkAllSelect({children:data},'a10004')":indeterminate="indeterminateCheck({children:data},'a10004') && !checkAllSelect({children:data},'a10004')"slot="customQuery">查詢</a-checkbox><template slot="checkBoxEntry" slot-scope="text,item"><template v-if="item.authButtonGroup"><a-checkbox @change="onChangeRecord($event,item,'a10001')" v-if="item.authButtonGroup.includes('a10001')" :checked="item.authButton.includes('a10001')"></a-checkbox><span v-else></span></template><a-checkbox @change="onChangeRecordMenu($event,item,'a10001')" v-else-if="item.children.some(inner => inner.authButtonGroup.includes('a10001'))" :checked="checkAllSelect(item,'a10001')":indeterminate="indeterminateCheck(item,'a10001') && !checkAllSelect(item,'a10001')"></a-checkbox><span v-else></span></template><template slot="checkBoxEdit" slot-scope="text,item"><template v-if="item.authButtonGroup"><a-checkbox @change="onChangeRecord($event,item,'a10002')" v-if="item.authButtonGroup.includes('a10002')" :checked="item.authButton.includes('a10002')"></a-checkbox><span v-else></span></template><a-checkbox @change="onChangeRecordMenu($event,item,'a10002')" v-else-if="item.children.some(inner => inner.authButtonGroup.includes('a10002'))" :checked="checkAllSelect(item,'a10002')":indeterminate="indeterminateCheck(item,'a10002') && !checkAllSelect(item,'a10002')"></a-checkbox><span v-else></span></template><template slot="checkBoxApproval" slot-scope="text,item"><template v-if="item.authButtonGroup"><a-checkbox @change="onChangeRecord($event,item,'a10003')" v-if="item.authButtonGroup.includes('a10003')" :checked="item.authButton.includes('a10003')"></a-checkbox><span v-else></span></template><a-checkbox @change="onChangeRecordMenu($event,item,'a10003')" v-else-if="item.children.some(inner => inner.authButtonGroup.includes('a10003'))" :checked="checkAllSelect(item,'a10003')":indeterminate="indeterminateCheck(item,'a10003') && !checkAllSelect(item,'a10003')"></a-checkbox><span v-else></span></template><template slot="checkBoxQuery" slot-scope="text,item"><template v-if="item.authButtonGroup"><a-checkbox @change="onChangeRecord($event,item,'a10004')" v-if="item.authButtonGroup.includes('a10004')" :checked="item.authButton.includes('a10004')"></a-checkbox><span v-else></span></template><a-checkbox @change="onChangeRecordMenu($event,item,'a10004')" v-else-if="item.children.some(inner => inner.authButtonGroup.includes('a10004'))" :checked="checkAllSelect(item,'a10004')":indeterminate="indeterminateCheck(item,'a10004') && !checkAllSelect(item,'a10004')"></a-checkbox><span v-else></span></template></a-table></div> </template><script> export default {name: 'EnumModal',data() {return {columns: [{title: '授權(quán)菜單',dataIndex: 'title',key: 'title' },{dataIndex: 'entry',key: 'entry',align:'center',slots: { title: 'customEntry' },scopedSlots: { customRender: 'checkBoxEntry' }},{dataIndex: 'edit',align:'center',key: 'edit',slots: { title: 'customEdit' },scopedSlots: { customRender: 'checkBoxEdit' }},{dataIndex: 'approval',align:'center',key: 'approval',slots: { title: 'customApproval' },scopedSlots: { customRender: 'checkBoxApproval' }},{dataIndex: 'query',align:'center',key: 'query',slots: { title: 'customQuery' },scopedSlots: { customRender: 'checkBoxQuery' }}],data: []}},created(){this.getTableData();},methods: {// 校驗(yàn)一個(gè)是否存在menucode或者子節(jié)點(diǎn)存在checkAllSelect(item,authCode){// 找到一個(gè)不滿足let flag = true;let children = item.children;if(!item || !item.children){return false;}let stack = [];while(children){children.some(item=>{if(item.authButtonGroup){if(item.authButtonGroup.includes(authCode)){flag = item.authButton.includes(authCode);return !flag;}}else{stack.push(item);return false;}})// 找到了不向下執(zhí)行if(!flag){break;}let next = stack.shift();children = next ? next.children : '';}return flag;},// 校驗(yàn)是否是半選狀態(tài)indeterminateCheck(item,authCode){// 至少有一個(gè)選中l(wèi)et flag = false;let children = item.children;let stack = [];while(children){children.some(item=>{if(item.authButtonGroup){if(item.authButtonGroup.includes(authCode)){flag = item.authButton.includes(authCode);return flag;}}else{stack.push(item);return false;}})// 找到了有一個(gè)if(flag){break;}let next = stack.shift();children = next ? next.children : '';}return flag;},onChangeAll(event,authCode){let data = this.data.filter(item=>{return item.menuCode != 82;})let flag = this.checkAllSelect({children:this.data},authCode);event.target.checked = !flag;this.onChangeRecordMenu(event,{children:data},authCode);},onChangeRecordMenu(event,record,authCode){let flag = event.target.checked;let children = record.children;let stack = [];while(children){console.log(children);children.forEach(item=>{if(item.authButtonGroup){if(item.authButtonGroup.includes(authCode)){if(flag){this.compareDleteOrAdd(item.authButton,authCode,true,false);}else{this.compareDleteOrAdd(item.authButton,authCode,false,true);}}}else{stack.push(item);}})let next = stack.shift();children = next ? next.children : '';}this.$forceUpdate();},onChangeRecord(event,record,authCode){this.compareDleteOrAdd(record.authButton,authCode,true,true);this.$forceUpdate();},// 在數(shù)組中增加或者減少一項(xiàng)compareDleteOrAdd(arr,item,isAdd,isDel){let index = arr.indexOf(item)if(index > -1){if(isDel){arr.splice(index,1);}}else{if(isAdd){arr.push(item);}}return index;},getTableData() {let promises = [獲取人員權(quán)限,獲取表格樹(shù)];Promise.all(promises).then(result=>{let authButton = result[0].responseList;let authButtonMap = {};Array.isArray(authButton) && authButton.forEach(item=>{authButtonMap[item.menu_code] = item.authority_button_codes ? item.authority_button_codes.split(',') : [];})let data = [...result[1].responseList];function dealTree(item){let child = item.children;if(Array.isArray(child)){if(child.length == 0){item.authButtonGroup = ['a10004'];}else {child.forEach(inner=>{if(inner.title){dealTree(inner)}else{!item.authButtonGroup && (item.authButtonGroup = []);item.authButtonGroup.push(inner.authority_button_code);}})}}if(item.authButtonGroup){item.authButton = authButtonMap[item.menuCode] || [];delete item.children;}return item;}this.data = data.map(item=>{return dealTree(item);});}, } </script>

    總結(jié)

    以上是生活随笔為你收集整理的树形选择变成表格树选择的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。