#直接上代码#
1.表格数据
2.数据源
<m-table
ref="cTable"
v-if="Object.keys(props.tableData).length"
:options="props.tableOptions"
:data="props.tableData.data"
:isLoading="props.tableData.loading"
elementLoadingText="加载中..."
elementLoadingBackground="rgba(0,0,0,.8)"
isEditRow
lazy
row-key="id"
:load="loadTree"
:tree-props="{ children: 'lstChildrenModule', hasChildren: 'hasChildren' }"
:header-cell-style="props.tableClass.headerCellStyle"
border>
<!--操作栏-->
<template #subAction="scope">
<el-tooltip effect="dark" content="添加子菜单" placement="top-start">
<el-button circle :icon="Plus" size="small" type="primary"
@click="toMenuEditAdd(scope.scope.row, 'subAdd')"></el-button>
</el-tooltip>
<el-tooltip effect="dark" content="修改平台" placement="top-start">
<el-button circle :icon="Edit" size="small" type="primary"
@click="toMenuEditAdd(scope.scope.row, 'edit')"></el-button>
</el-tooltip>
<el-tooltip effect="dark" content="删除平台" placement="top-start">
<el-button circle :icon="Delete" size="small" type="danger"
@click="onRowDel(scope.scope.row, 'del')"></el-button>
</el-tooltip>
</template>
<!--操作栏-->
</m-table>
3 运行结果
4.初始化懒加载数据
let cTable = ref();
const loadMap = new Map();
/**
* 懒加载菜单
* @times 2023-09-04 16:46
* @link https://blog.csdn.net/a4561614
* @param {row,treeNode,resolve}
* @returns []
* @method loadTree 懒加载菜单
*/
const loadTree = async (row, treeNode, resolve) => {
let obj = {
"moduleNo": "", //模块编号
"moduleName": "", //模块名称
"parentNo": row.moduleNo, //父编号
"appNo": row.appNo, //平台编号
"isDelete": false
}
let res = await useMenuApi().getModulesAll(obj)
setTimeout(() => {
//将获取到的节点数据添加到loadMap缓存中,用于每次操作节点时进行过滤判断
loadMap.set(row.moduleNo, { row, treeNode, resolve });
resolve(res.results)
}, 1000)
};
5,全局添加/子菜单添加/编辑
//引入每次点击保存再数据管理层用于判断更新节点
import { paremData } from '/@/stores/paremData';
/**
* @author ken
* @version 1.0
* @method addMenuEditModal 弹窗
* @description 新增菜单
*/
let addMenuEditModal = (row,type) => {
state.menuData.type = type;
// menuRef.value?.restForm();
//如果是菜单添加时,当前行的模块名称为父节点parentNo数据
//如果是编辑时,当前行的模块名称为模块名称,当前行的父节点parentNo为parentNo数据
state.menDefaultsData=type=='edit'?row:{}
state.menDefaultsData.parentNo= type=='add'?'': (type=='edit'?row.parentNo:row.moduleNo);
//如果是点击编辑和新增子菜单时存入当前行的row数据
paremData().setTreeRow((type=='edit' || type=='subAdd' )?row: {});
state.menuData.title =type=='edit'?"编辑菜单": "添加菜单";
state.menuData.okTxt = type=='edit'?"确定编辑": "确定";
menuDialogVisibles.value = true;
}
/**
* @author ken
* @version 1.0
* @param {form}
* @method confirmMenuData
* @description 新增菜单提交数据
*/
const confirmMenuData = (form)=>{
let validate = form.validate()
let model = form.getFormData()
validate(async (valid) => {
if (valid) {
if(model.parentNo instanceof Array){
model.parentNo=model.parentNo.toString();
}
if(!model.appNo){
model.appNo=paremData().getAppNo?paremData().getAppNo:row.appNo;
}
let res = await useMenuApi().moduleSaveOrUpdate(model)
if (!res.hasErr) {
menuDialogVisibles.value = false;
ElMessage.success(res.msg);
//如果是子菜单添加,通过当前点击的行内数据hasChildren判判断是否存在二级或者多级数据,当为true时 取parentNo作为父节点,为false 吧moduleNo为父节点
//通过parentNo,moduleNo 到 loadMap 去缓存中查找数据,然后通过查找出来的数据中取 (id ,因为table中定义了 row-key="id")进行过滤重置或者清除Tree缓存数据,
//如果不存在就直接刷新当前页面
if(option.menuData.type=='subAdd' || option.menuData.type=='edit'){
let row=paremData().getTreeRow;
containerSideRef.value.reloadTree(row.hasChildren==false?row.parentNo:row.moduleNo);
}
if(option.menuData.type=='add'){
getModulesPageData();
}
menuRef.value?.restForm()
} else {
ElMessage.error(res.msg);
}
}
})
}
/**
* @author ken
* @version 1.0
* @param {row,type}//当前行的数据,类型为删除
* @method removeMenuData
* @description 删除子节点后,去刷新页面
*/
const removeMenuData = (row,type)=>{
ElMessageBox.confirm(`此操作将永久删除:${row.moduleName}, 是否继续?`, '提示', {
confirmButtonText: '删除',
cancelButtonText: '取消',
type: 'warning',
})
.then(async() => {
let res=await useMenuApi().removeModules({moduleNo:row.moduleNo,isDelete:true});
if(!res.hasErr){
containerSideRef.value.reloadTree(row.parentNo);
ElMessage.success('删除成功');
}else{
ElMessage.error(res.msg)
}
})
.catch(() => {});
}
/**
* @times 2023-09-04 16:46
* @link https://blog.csdn.net/a4561614
* @param {parentNo}
* @returns []
* @method reloadTree 重新懒加载菜单栏
*/
const reloadTree = (parentNo) => {
parentNo = parentNo ? parentNo : '';
//从const loadMap = new Map();判断是否存在
let objs = loadMap.get(parentNo);
if (objs == undefined || objs == '') {
//刷新页面
emits('refresh-menu-data')
} else {
//执行通过id清除缓存中的数据
const { row, treeNode, resolve } = objs;
cTable.value.removeCacheTree(row.id);
//重新懒加载一次
loadTree(row, treeNode, resolve);
}
};
/**
* @author ken
* @version 1.0
* @param row 刷新子节点数据
* @method removeCacheTree 清除事件
* @description //刷新子节点数据
*/
const removeCacheTree=(id)=>{
//通过ref获取table的子节点数
if (table_ref.value.store.states.lazyTreeNodeMap.value[id].length > 1) {
//说明该节点下有多个子节点
table_ref.value.store.states.lazyTreeNodeMap[id] = [];
} else {
//说明该节点只有一个节点
table_ref.value.store.states.lazyTreeNodeMap.value[id] = [];
}
}
6.paremData.js
import { defineStore } from 'pinia';
/**
* 参数数据管理
* @methods setParemData 设置参数数据管理
*/
export const paremData = defineStore('paremStoreData', {
state: () => ({
treeRow:{}//树形菜单当前行缓存
}),
getters:{
getTreeRow(state){
return state.treeRow
}
},
actions: {
setTreeRow(row){
//存储树形行菜单数据
this.treeRow=row;
}
},
});
!完结