需求
- 点击table表格中的编辑时,表格中的上级部门可以替换位置。而且添加成功后,表格之前的状态不能改变(可以理解为展开项不变)
- 添加子部门时,也可以替换位置,添加成功后,要求同上。
解决问题思路
- 首先表格和弹框中的select下拉框tree都是懒加载。
- 实现表格和tree的联动,思路:存一个表格展开的当前项,将这个数据传给下拉框中的tree,取出全部展开的id 赋值给tree的展开属性。
- 实现tree和table表格的联动,利用tree展开事件,直接调取table中的loadOrToggle方法。
- 编辑
- 父级部门不改变时,直接将修改的值进行赋值即可。
- 父级部门改变时,将当前节点进行克隆,删除当前节点,然后找到需要的父节点下的懒加载数据,如果父节点下没有子节点,则将其haschilren属性改为true,然后直接调用loadOrTogg即可,如果有字节点,将其添加进最后一项即可。
- 添加子部门
- 父节点是当前节点时,判断当前父节点下是否有子节点,如果父节点下没有子节点,则将其haschilren属性改为true,然后直接调用loadOrTogg即可,如果有字节点,将其添加进懒加载数据的最后一项。
- 父节点不是当前节点时,找到父节点。判断当前父节点下是否有子节点,如果父节点下没有子节点,则将其haschilren属性改为true,然后直接调用loadOrTogg即可,如果有字节点,将其添加进懒加载数据的最后一项。
所用的elment源码方法
- this.$refs.table.store.states.lazyTreeNodeMap[id];
- 获取table 懒加载数据的方法
- id 父级id 获取这个id下所有的懒加载节点
- this.$refs.table.store.loadOrToggle(row);
代码部门
table和tree 联动的核心代码
table组件的代码
<el-table
id="table"
ref="table"
:key="config.key"
v-loading="config.loading"
:data="tableData"
tooltip-effect="dark"
style="width: 100%"
row-key="id"
:lazy="config.isLazy"
:expand-row-keys="config.expandID"
:load="load"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
class="mt-33 divide-transdataList"
@selection-change="handleSelectionChange"
@select-all="selectAll"
@expand-change="expandChange"
>
</el-table>
methods:{
/** 点击展开table icon触发
*@parame row 展开或者关闭的当前项
*@parame expandedRows 展开则为true 关闭则为false
*/
expandChange(row, expandedRows) {
//获取当前项在展开数据中位置
let index = this.config.expandNode.findIndex(item => item.id == row.id);
//如果是展开,将其加入展开数组中
if (expandedRows == true) {
if (index == -1) {
this.config.expandNode.push(row);
}
} else {
//如果是关闭,将其懒加载的状态设置为false
//将其移出展开数组
if (index > -1) {
this.setLoad(row.id);
this.config.expandNode.splice(index, 1);
}
}
},
/** 关闭当前懒加载节点的懒加载状态
* @parame id 需要改变懒加载状态的懒加载节点
*/
setLoad(id) {
this.$refs.table.store.states.treeData[id].loaded = false;
},
}
tree组件的代码
<el-select ref="selectTree" v-model="config.selectVal" filterable placeholder="请选择" popper- class="division" class="w-328">
<el-option :value="config.selectId" :label="config.selectName">
<el-tree
ref="tree"
lazy
node-key="id"
:load="loadNode"
:default-expanded-keys="config.expandKeys"
:props="defaultProps"
:expand-on-click-node="false"
@node-expand="handleExpand"
@node-collapse="handleExpand"
@node-click="handleNodeClick"
></el-tree>
</el-option>
</el-select>
watch: {
async addVisible(val) {
//弹框显示的时候
if (val) {
//tree的默认展开,实现表格和tree联动
config.expandKeys = [];
this.expandNode?.forEach(item => {
config.expandKeys.push(item.id);
});
}
//这里做一些回显的操作
},
methods:{
//tree树展开关闭触发
handleExpand(item) {
//联动父级组件的table 表格展开关闭
//因为父组件展开关闭有函数expandChange,所以这里已经实现tree联动表格了。
this.$parent.$refs.table?.store.loadOrToggle(item);
},
/**点击tree 设置父节点
* @params item 所点击的当前项
*/
handleNodeClick(item) {
let config = this.config;
this.parentNode = item;
config.selectVal = config.selectId = item.id;
config.selectName = item.name;
this.$refs.selectTree.blur();
//编辑操作时,上级部门没有改变,而且用户层时,父级id必须为''否则报错
if (config.selectVal == this.tenantInfo?.id) {
this.parentNode.id = '';
}
},
}
添加子部门
/**添加弹框点击确认执行函数
*@parame Object val 点击当前项
*@parame String type 添加子部门还是编辑或者是新建
*@parame Object addRow 添加的项
*/
appendChildren(val, type, addRow){
//当val是选择的值时时tree的数据,所以需要关联到table表格的数据
let selectNode;
//如果是tableData的数据 获取到它的所在位置 设置hasChilds属性为true 展开符
if (val.parentId == '') {
selectNode = this.tableData.filter(item => item.id == val.id);
selectNode[0].hasChildren = true;
}
//同上 区别是这是懒加载的数据
if (val.parentId) {
const loadList = this.getLazyData(val.parentId);
selectNode = loadList.filter(item => item.id == val.id);
selectNode[0].hasChildren = true;
}
//判断当前是否有展开的数据 如若没有则直接调用懒加载
if (this.config.expandNode.length == 0) {
this.$nextTick(() => {
this.loadOrToggle(selectNode[0]);
});
} else {
//判断添加子部门的父级是否是展开状态,如果是就添加到子级数据 如果不是就懒加载打开
let isExpand = this.config.expandNode.some(item => item.id == val.id);
//如果父节点展开,获取懒加载数据,将数据添加至数据中
if (isExpand) {
const dataList = this.getLazyData(selectNode[0].id);
dataList && dataList.push(addRow);
} else {
if (type == 'edit') {
if (val.parentId == '' || val.parentId) {
this.$nextTick(() => {
this.loadOrToggle(selectNode[0]);
});
} else {
Object.assign(addRow, { parentId: '', parentName: '' });
this.tableData.push(addRow);
}
} else {
//父节点没有展开,直接调用懒加载方法
this.$nextTick(() => {
this.loadOrToggle(selectNode[0]);
});
}
}
}
},
/** 获取table 懒加载数据的方法
* @parame id 父级id 获取这个id下所有的懒加载节点
*/
getLazyData(id) {
return this.$refs.table.store.states.lazyTreeNodeMap[id];
},
/** 懒加载或者展开关闭节点
* @parame row 节点
*/
loadOrToggle(row) {
this.$refs.table.store.loadOrToggle(row);
},