<template>
<div class="half-transfer">
<div class="el-transfer-panel">
<div>
<el-checkbox v-model="selectAll" @change="handleSelectAll">全部</el-checkbox>
</div>
<el-input v-model="searchInput" placeholder="请输入搜索内容" clearable @clear="clearSearch"></el-input>
<div class="el-transfer__list">
<el-tree
ref="treeRef"
:data="treeData"
node-key="key"
:default-expand-all="true"
show-checkbox
:default-checked-keys="checkedKeys"
:filter-node-method="filterNode"
@check="handleCheckChange"
></el-tree>
</div>
</div>
</div>
</template>
<script setup>
import { ref, reactive, watch, nextTick } from 'vue';
import { ElTree, ElCheckbox, ElInput } from 'element-plus';
const searchInput = ref('');
const checkedKeys = ref([]);
const treeData = reactive([
{
key: 1,
label: '选项1',
children: [
{ key: 11, label: '子选项11' },
{ key: 12, label: '子选项12' },
{ key: 13, label: '子选项13' },
],
},
{
key: 2,
label: '选项2',
children: [
{ key: 21, label: '子选项21' },
{ key: 22, label: '子选项22' },
{ key: 23, label: '子选项23' },
],
},
]);
const selectAll = ref(false);
const treeRef = ref(null);
watch(searchInput, (val) => {
treeRef.value.filter(val);
});
const filterNode = (value, data) => {
if (!value) return true;
return data.label.includes(value);
};
const clearSearch = () => {
searchInput.value = '';
};
const handleSelectAll = (checked) => {
if (checked) {
checkedKeys.value = getAllNodeKeys();
} else {
checkedKeys.value = [];
treeRef.value.setCheckedKeys([]);
}
};
const getAllNodeKeys = () => {
const keys = [];
const traverse = (nodes) => {
for (const node of nodes) {
keys.push(node.key);
if (node.children && node.children.length > 0) {
traverse(node.children);
}
}
};
traverse(treeData);
return keys;
};
const handleCheckChange = (data) => {
checkedKeys.value = data.checkedKeys;
// 获取树节点选中的id
console.log(treeRef.value.getCheckedKeys())
nextTick(() => {
if (treeRef.value) {
const nodes = treeRef.value.root.childNodes;
const allChecked = nodes.every((node) => node.checked);
selectAll.value = allChecked;
}
});
};
</script>
<style scoped>
.half-transfer {
margin-top: 20px;
margin-left: 20px;
width: 335px;
height: 260px;
background: #fff;
padding: 20px;
border: 1px solid #dcdfe6;
border-radius: 4px;
}
.el-transfer-panel {
display: flex;
flex-direction: column;
height: 100%;
}
.el-transfer__list {
overflow-y: auto;
border-radius: 4px;
margin-top: 8px;
}
.el-transfer__list .el-checkbox-group {
padding: 10px;
}
.el-transfer__list .el-checkbox {
display: block;
margin-bottom: 5px;
line-height: 24px;
}
.el-transfer__list .el-checkbox:last-child {
margin-bottom: 0;
}
.el-transfer__list .el-scrollbar {
background-color: #f5f7fa;
}
</style>