我实现的效果是:
el-select 下拉框嵌套el-tree 树形组件 完成多选、删除、清空选项等联动功能
我的数据结构有两层,只能选中第二层节点数据
<el-select
class="el-input-search"
v-model="ruleForm.releasePerson"
ref="orgtxSelect"
:multiple="true"
placeholder="发布人员"
@remove-tag="removetag"
@clear="clearall"
clearable
@change="$forceUpdate()"
style="width: 300px"
>
<el-option
disabled
value=""
style="height: auto; background-color: #fff"
class="noDisabledCursor"
>
<el-input
:validate-event="false"
v-model="filterText"
placeholder="请输入"
@click.stop.native
style="margin: 10px 0"
></el-input>
<el-tree
:data="orgList"
show-checkbox
default-expand-all
highlight-current
:expand-on-click-node="false"
:check-on-click-node="true"
node-key="id"
@node-click="handleNodeClick"
@check="handleNodeCheck"
:check-strictly="true"
class="dialogTree"
ref="orgtxtree"
></el-tree>
</el-option>
</el-select>
需要的数据
data() {
return {
ruleForm: {
releasePerson: null,
},
orgList: [],//获取的树节点数据
selectTree: [], //选中的树节点
treeIds: [], //选中的id
filterText: "",
};
},
watch: {
//type为user为第二层节点的数据 第一层的type为null
selectTree(val) {
if (val && val.length) {
const list = val.filter((item) => item.type === "user");
this.treeIds = list.map((item) => item.id);
this.ruleForm.releasePerson = list.map((item) => item.label);
}
},
//树节点模糊搜索
filterText(val) {
this.$refs.orgtxtree.filter(val);
},
},
用到的方法
handleNodeClick(data, node) {
if (!data.children && data.type === "user") {
const nodeId = data.id; // 假设每个节点有一个唯一的 id 属性
const selectedNodes = this.treeIds; // 获取当前选中的节点值数组
const isChecked = node.checked; // 获取当前节点的选中状态
if (isChecked && !selectedNodes.includes(nodeId)) {
// 如果节点被选中且其值不在选中数组中,则添加该值
selectedNodes.push(nodeId);
} else if (!isChecked && selectedNodes.includes(nodeId)) {
// 如果节点被取消选中且其值在选中数组中,则移除该值
const index = selectedNodes.indexOf(nodeId);
if (index > -1) {
selectedNodes.splice(index, 1);
}
}
this.$forceUpdate();
}
},
handleNodeCheck(data, node) {
if (!data.children && data.type === "user") {
this.selectTree = [];
node.checkedNodes.forEach((item) => {
this.selectTree.push({
id: item.id,
label: item.label,
type: item.type ? item.type : null,
});
});
}
},
//点击select中删除按钮方法实现
removetag(val) {
let checkNodes = this.$refs.orgtxtree.getCheckedNodes();
let keyArrList = this.$refs.orgtxtree.getCheckedKeys();
let selectList = this.selectTree.map((x) => x.label);
for (let i = 0; i < checkNodes.length; i++) {
if (checkNodes[i].label == val) {
if (checkNodes[i].children && checkNodes[i].children.length > 0) {
keyArrList.splice(i, 1);
this.selectTree.splice(selectList.indexOf(val), 1);
this.del(checkNodes[i].children, keyArrList);
} else {
checkNodes.splice(i, 1);
this.selectTree.splice(selectList.indexOf(val), 1);
this.$refs.orgtxtree.setCheckedNodes(checkNodes);
}
break;
}
}
},
// 递归删除树组件选中状态
del(arr, dataList) {
for (let item of arr) {
if (item.children && item.children.length > 0) {
this.del(item.children);
} else {
dataList.splice(dataList.indexOf(Number(item.id)), 1);
}
}
this.$nextTick(() => {
this.$refs.orgtxtree.setCheckedKeys(dataList);
});
},
clearall() {
this.selectTree = [];
this.treeIds = [];
this.$nextTick(() => {
this.$refs.orgtxtree.setCheckedNodes([]);
});
},
filterNode(value, data) {
if (!value) return true;
if (data.label) {
return data.label.indexOf(value) !== -1;
}
},