树多选搜索查询,搜索后选中状态仍保留

javascript 复制代码
<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>
相关推荐
镜宇秋霖丶2 天前
2026.5.10@霖宇博客制作中遇见的问题
前端·vue.js·elementui
莫生灬灬2 天前
ElementUI封装 共91个组件 支持易语言/火山/C#/Python
开发语言·c++·python·ui·elementui·c#
镜宇秋霖丶4 天前
2026.5.8@霖宇博客制作中遇见的问题
前端·vue.js·elementui
MXN_小南学前端4 天前
Vue + Element UI 分页器封装:比直接用 el-pagination 更省心的通用方案
javascript·vue.js·elementui
invicinble4 天前
前端框架使用vue-cli( 第二层:工程配置层--elementui需要做的基础配置)
vue.js·elementui·前端框架
周bro7 天前
vue2+element ui 中的el-table表格 选中当前行当前行变色,单选/多选--------续集:表格样式修改整合
vue.js·ui·elementui
T畅N8 天前
审批流设计器(前端)
前端·elementui·vue·html·流程图·js
abcnull8 天前
Springboot+Vue2的Web项目小白入门Demo快速学习!
java·elementui·vue·maven·springboot·web·小白
abcnull9 天前
传统的JavaWeb项目Demo快速学习!
java·servlet·elementui·vue·javaweb
FlyWIHTSKY15 天前
router-viiew没有滚动条,如何修复
前端·vue.js·elementui