使用element-tree实现id相同的选择
- 相同人员可在不同部门出现, 当勾选其中一个人员时,其它部门的相同人员也要勾选上
- 右侧可进行删除已勾选人员, 并且树状图勾选状态取消
- 若有勾选,进入时候默认选中
效果如下:
例如: 点击勾选总经办的王五,技术部的王五也要勾选上,右侧删除王五的时候,左侧相关王五的勾选全部取消
因为element-tree出现重复id的时候,会导致被覆盖,只能勾选中一个,
解决方案: 修改element-ui tree的源码
tree-store.js 文件 仿照源码增加了两个自定义的方法
export default class TreeStore {constructor(options) {this.currentNode = null;this.currentNodeKey = null;for (let option in options) {if (options.hasOwnProperty(option)) {this[option] = options[option];}}this.nodesMap = {};//mycodethis.myNodesMap = [];this.root = new Node({data: this.data,store: this});if (this.lazy && this.load) {const loadFn = this.load;loadFn(this.root, (data) => {this.root.doCreateChildren(data);this._initDefaultCheckedNodes();});} else {this._initDefaultCheckedNodes();}}//mycodesetMyChecked(data, checked, deep) {const nodes = this.getMyNode(data);if (nodes && nodes.length > 0) {for (let index = 0; index < nodes.length; index++) {const element = nodes[index];let node = Object.values(element)[0];if (node&&(node.checked!==checked)) {node.setChecked(!!checked, deep);}}}}//mycodegetMyNode(data) {const key = typeof data !== 'object' ? data : getNodeKey(this.key, data);const result = this.myNodesMap.filter(item => item[key]);return result || [];}registerNode(node) {const key = this.key;if (!key || !node || !node.data) return;const nodeKey = node.key;if (nodeKey !== undefined) this.nodesMap[node.key] = node;//mycodeif (nodeKey !== undefined) {this.myNodesMap.push({[node.key]: node});}}
tree.vue 文件增加自定义设置的方法
//mycodesetMyChecked(data, checked, deep) {this.store.setMyChecked(data, checked, deep);},
注意: 由于更改了依赖的源码 需要额外进行处理 我在这的处理方法是 : 将ele 的tree复制单独使用lib文件夹存放
因为修改了依赖 使用了自定义的方法,直接改动依赖打印东西,是没有任何效果的,需要进行引入组件再打印
//代码有删减
<template><div><div class="distribution"><div class="people"><div class="search"><el-inputplaceholder="请输入内容"v-model="filterText"clearableclass="input-with-select"><el-button slot="append" icon="el-icon-search" @click="filterNode"></el-button></el-input><el-buttontype="primary"class="refreshico"icon="el-icon-refresh-left"size="mini"@click="handleAsync">同步数据</el-button></div><div class="tree"><el-treeclass="filter-tree":data="depData":props="defaultProps"default-expand-allhighlight-currentnode-key="id":expand-on-click-node="false":filter-node-method="filterNode"@check-change="handleCheckChange"ref="tree"show-checkbox></el-tree></div></div><div class="selectPeople"><div><span class="selectText">已选员工</span><div class="delAll" @click="delAll">清空</div></div><ul><li v-for="(item, index) in selectList" :key="index"><span>{{ item.workDeptId }}</span><div @click="handleDelSelect(item)">x</div></li></ul></div></div><div class="tree_btn"><el-button type="danger" @click="handleCancel">取消</el-button><el-button type="primary" @click="save">确认</el-button></div></div>
</template><script>
import ElTree from "@/lib//tree/src/tree.vue";
import peopelList from './index.json';
export default {props: ["selectUserIdList"],components: {ElTree,},data() {return {isDel: false,depData: [],checkedKeyList: [],selectList: [],defaultProps: {children: "childrenDepartmentList",label: "workDeptId",},distribution: false,agentConfigSuccess: false,queryParams: {},filterText:'',};},methods: {// 选择员工内的删除handleDelSelect(data) {this.$refs.tree.setMyChecked &&this.$refs.tree.setMyChecked(data, false, true);},//去重,因为相同人员可以在不同部门出现,右侧进行渲染只渲染一个名字unique(arr) {const res = new Map();return arr.filter((a) => !res.has(a.workDeptId) && res.set(a.workDeptId, 1) && a.type === 'user');},// 多选框选中handleCheckChange(data, checked, indeterminate) {//设置选择框状态data.id &&this.$refs.tree.setMyChecked &&this.$refs.tree.setMyChecked(data, checked, true);//右边渲染列表let workDeptIds = this.$refs.tree.getCheckedNodes().filter((item) => item.id && item.childrenDepartmentList.length === 0);this.selectList = this.unique(workDeptIds);},filterNode(value, data) {if (!value) return true;return data.workDeptId.indexOf(value) !== -1;},//因为我这里初始默认选中的数据结构和 部门列表的数据结构不一致,所以我进行了多一层处理//将初始默认选中的数据传入进行过滤,将过滤成功的数据进行勾选并渲染myFilter(value) {let _this = thisconst traverse = function (node) {const childNodes = node.root ? node.root.childNodes : node.childNodes;childNodes.forEach((child) => {if(child.data.workDeptId === value){_this.$refs.tree.setMyChecked(child.data, true, true);}traverse(child);});};traverse(this.$refs.tree);},// 取消handleCancel() {this.$emit("handleCancel", false);this.filterText = "";this.selectList = "";this.$refs.tree.setCheckedKeys([]);},// 清空已选员工delAll() {this.selectList = [];this.checkedKeyList = [];this.$refs.tree.setCheckedKeys([]);},save(){if(this.selectList.length){this.$emit('handleConfirm',this.selectList)}else{this.$message({showClose: true,message: '请选择员工',type: 'error'});}},},watch: {filterText(val) {let data = {userName:val.trim()}workServiceUser(data).then(res=>{if(res && res.data && res.data.length){res.data.map(item=>{this.$refs.tree.filter(item);})}else{this.$refs.tree.filter(val);}})},"selectUserIdList":{handler(){this.$nextTick(()=>{if(this.selectUserIdList && this.selectUserIdList.length){this.selectUserIdList.map(item=>{this.myFilter(item)})}})}},},
};
</script>
觉得赞的话可以打赏下哦~