Luka 10 timmar sedan
förälder
incheckning
c6df2ad77b
1 ändrade filer med 158 tillägg och 166 borttagningar
  1. 158 166
      src/views/addressBook/components/treeSelect.vue

+ 158 - 166
src/views/addressBook/components/treeSelect.vue

@@ -1,96 +1,46 @@
 <template>
-  <div class="tree-container">
-    <!-- 搜索区域 -->
-    <div class="search-bar">
-      <el-input
-        v-model="searchKeyword"
-        placeholder="快速检索"
-        class="search-input"
-        prefix-icon="Search"
-      />
-      <el-button type="primary" class="search-btn" @click="handleSearch">查询</el-button>
-      <el-button type="default" class="reset-btn" @click="handleReset">重置</el-button>
-    </div>
-
-    <!-- 树形结构区域 -->
-    <div class="tree-wrapper">
-      <el-tree
-        v-model:checkedKeys="checkedKeys"
-        :data="treeData"
-        :props="treeProps"
-        show-checkbox
-        node-key="id"
-        :filter-node-method="filterNode"
-        ref="treeRef"
-        class="custom-tree"
-        :indent="16"
-        :icon="renderIcon"
-      />
-    </div>
-  </div>
+	<div class="tree-container">
+		<!-- 搜索区域 -->
+		<div class="search-bar">
+			<el-input v-model="searchKeyword" placeholder="快速检索" class="search-input" prefix-icon="Search" />
+			<el-button type="primary" class="search-btn" @click="handleSearch">查询</el-button>
+			<el-button type="default" class="reset-btn" @click="handleReset">重置</el-button>
+		</div>
+
+		<!-- 树形结构区域 -->
+		<div class="tree-wrapper">
+			<el-tree
+				ref="treeRef"
+				v-model:checkedKeys="checkedKeys"
+				:data="treeData"
+				:props="treeProps"
+				default-expand-all
+				highlight-current
+				show-checkbox
+				check-on-click-node
+				node-key="id"
+				:filter-node-method="filterNode"
+				@current-change="handleCheckChange"
+				class="custom-tree"
+			/>
+		</div>
+	</div>
 </template>
 
 <script setup lang="ts">
 import { ref, computed } from 'vue';
 import { ElTree } from 'element-plus';
-import { CircleClose, CircleCheck } from '@element-plus/icons-vue';
-
-// 树形结构数据(模拟后端返回数据)
-const treeData = ref([
-  {
-    id: 1,
-    label: '交通部根节点',
-    children: [
-      { id: 11, label: 'XXXXXXXX机构', checked: true },
-      { 
-        id: 12, 
-        label: 'XXXXXXXX机构', 
-        checked: true,
-        children: [
-          { id: 121, label: 'XXXXXXXX机构', checked: true },
-          { id: 122, label: 'XXXXXXXX机构' },
-          { id: 123, label: 'XXXXXXXX机构' },
-          { id: 124, label: 'XXXXXXXX机构' },
-          { id: 125, label: 'XXXXXXXX机构' },
-          { id: 126, label: 'XXXXXXXX机构', checked: true },
-        ]
-      },
-      { 
-        id: 13, 
-        label: 'XXXXXXXX机构', 
-        checked: true,
-        children: [
-          { id: 121, label: 'XXXXXXXX机构', checked: true },
-          { id: 122, label: 'XXXXXXXX机构' },
-          { id: 123, label: 'XXXXXXXX机构' },
-          { id: 124, label: 'XXXXXXXX机构' },
-          { id: 125, label: 'XXXXXXXX机构' },
-          { id: 126, label: 'XXXXXXXX机构', checked: true },
-        ]
-      },
-      { 
-        id: 14, 
-        label: 'XXXXXXXX机构', 
-        checked: true,
-        children: [
-          { id: 121, label: 'XXXXXXXX机构', checked: true },
-          { id: 122, label: 'XXXXXXXX机构' },
-          { id: 123, label: 'XXXXXXXX机构' },
-          { id: 124, label: 'XXXXXXXX机构' },
-          { id: 125, label: 'XXXXXXXX机构' },
-          { id: 126, label: 'XXXXXXXX机构', checked: true },
-        ]
-      },
-    ]
-  }
-]);
 
 // 树形配置项
-const treeProps = ref({
-  label: 'label',
-  children: 'children',
-  disabled: (data: any) => data.disabled, // 可自定义禁用节点
-});
+const treeProps = {
+	label: 'label',
+	children: 'children',
+};
+interface Tree {
+	id: number;
+	label: string;
+	children?: Tree[];
+}
 
 // 搜索关键词
 const searchKeyword = ref('');
@@ -98,112 +48,154 @@ const searchKeyword = ref('');
 const checkedKeys = ref<(string | number)[]>([]);
 // 树形组件实例
 const treeRef = ref<InstanceType<typeof ElTree>>();
+// 树形结构数据(模拟后端返回数据)
+const treeData = ref<Tree[]>([
+	{
+		id: 1,
+		label: '交通部根节点',
+		children: [
+			{ id: 11, label: 'XXXXXXXX机构11' },
+			{
+				id: 12,
+				label: 'XXXXXXXX机构12',
+				children: [
+					{ id: 121, label: 'XXXXXXXX机构121' },
+					{ id: 122, label: 'XXXXXXXX机构123' },
+					{ id: 123, label: 'XXXXXXXX机构123' },
+					{ id: 124, label: 'XXXXXXXX机构124' },
+					{ id: 125, label: 'XXXXXXXX机构125' },
+					{ id: 126, label: 'XXXXXXXX机构126' },
+				],
+			},
+			{
+				id: 13,
+				label: 'XXXXXXXX机构13',
+				children: [
+					{ id: 131, label: 'XXXXXXXX机构131' },
+					{ id: 132, label: 'XXXXXXXX机构132' },
+					{ id: 133, label: 'XXXXXXXX机构133' },
+					{ id: 134, label: 'XXXXXXXX机构134' },
+					{ id: 135, label: 'XXXXXXXX机构135' },
+					{ id: 136, label: 'XXXXXXXX机构136' },
+				],
+			},
+			{
+				id: 14,
+				label: 'XXXXXXXX机构14',
+				children: [
+					{ id: 141, label: 'XXXXXXXX机构141' },
+					{ id: 142, label: 'XXXXXXXX机构142' },
+					{ id: 143, label: 'XXXXXXXX机构143' },
+					{ id: 144, label: 'XXXXXXXX机构144' },
+					{ id: 145, label: 'XXXXXXXX机构145' },
+					{ id: 146, label: 'XXXXXXXX机构146' },
+				],
+			},
+		],
+	},
+]);
 
 // 过滤节点(搜索功能)
 const filterNode = (value: string, data: any) => {
-  if (!value) return true;
-  return data.label.toLowerCase().includes(value.toLowerCase());
+	if (!value) return true;
+	return data.label.toLowerCase().includes(value.toLowerCase());
+};
+
+const handleCheckChange = () => {
+	// // 参数:是否只含叶子、是否含半选(不全选,也显示父级数据)
+	// const checkedNodes = treeRef.value!.getCheckedNodes(false, false) as any[];
+	// console.log('所有选中的节点:', checkedNodes);
+	// 如果只想拿 key 数组  参数:是否只含叶子
+	checkedKeys.value = treeRef.value!.getCheckedKeys(false);
+	console.log('选中的 keys:', checkedKeys);
 };
 
 // 处理搜索
 const handleSearch = () => {
-  treeRef.value?.filter(searchKeyword.value);
+	treeRef.value?.filter(searchKeyword.value);
 };
 
 // 处理重置
 const handleReset = () => {
-  searchKeyword.value = '';
-  treeRef.value?.filter(''); // 清空搜索过滤
-};
-
-const renderIcon = (props: any) => {
-  if (!props.data) return null;
-  const isLeaf = !props.data.children || props.data.children.length === 0;
-  // 叶子节点且未勾选:空复选框图标
-  if (isLeaf && !props.checked) {
-    return h(CircleClose, { class: 'tree-icon unchecked' });
-  }
-  // 叶子节点且勾选:绿色勾选图标
-  if (isLeaf && props.checked) {
-    return h(CircleCheck, { class: 'tree-icon checked' });
-  }
-  return null;
+	searchKeyword.value = '';
+	treeRef.value!.setCheckedKeys([], false);
+	treeRef.value?.filter('');
 };
 </script>
 
 <style scoped lang="scss">
 .tree-container {
-  width: 100%;
-  padding: 20px;
-  background: #fff;
-  border-radius: 4px;
+	width: 100%;
+	padding: 20px;
+	background: #fff;
+	border-radius: 4px;
 }
 
-
 /* 搜索区域样式 */
 .search-bar {
-  display: flex;
-  align-items: center;
-  gap: 12px;
-  margin-bottom: 20px;
-
-  .search-input {
-    flex: 1;
-    height: 38px;
-    width: 150px;
-  }
-
-  .search-btn, .reset-btn {
-    min-width: 80px;
-    height: 38px;
-    padding: 0 16px;
-  }
-
-  .reset-btn {
-    border: 1px solid #dcdfe6;
-    color: #606266;
-    margin-left: 0;
-  }
+	display: flex;
+	align-items: center;
+	gap: 12px;
+	margin-bottom: 20px;
+
+	.search-input {
+		flex: 1;
+		height: 38px;
+		width: 150px;
+	}
+
+	.search-btn,
+	.reset-btn {
+		min-width: 80px;
+		height: 38px;
+		padding: 0 16px;
+	}
+
+	.reset-btn {
+		border: 1px solid #dcdfe6;
+		color: #606266;
+		margin-left: 0;
+	}
 }
 
 /* 树形结构样式 */
 .tree-wrapper {
-  border: 1px solid #e4e7ed;
-  border-radius: 4px;
-  max-height: 500px;
-  overflow-y: auto;
-  padding: 10px 0;
+	border: 1px solid #e4e7ed;
+	border-radius: 4px;
+	max-height: 500px;
+	overflow-y: auto;
+	padding: 10px 0;
 }
 
 .custom-tree {
-  --el-tree-node-content-hover-bg-color: transparent; /* 移除节点hover背景 */
-
-  .el-tree-node__content {
-    height: 36px;
-    align-items: center;
-  }
-
-  /* 复选框样式调整 */
-  .el-checkbox .el-checkbox__inner {
-    width: 18px;
-    height: 18px;
-    border-radius: 4px;
-  }
-
-  .el-checkbox__input.is-checked .el-checkbox__inner {
-    background-color: #10b981; /* 绿色勾选背景 */
-    border-color: #10b981;
-  }
-
-  /* 自定义图标样式 */
-  .tree-icon {
-    font-size: 18px;
-    &.checked {
-      color: #10b981; /* 绿色勾选图标 */
-    }
-    &.unchecked {
-      color: #c0c6cf; /* 未勾选灰色图标 */
-    }
-  }
+	--el-tree-node-content-hover-bg-color: transparent; /* 移除节点hover背景 */
+
+	.el-tree-node__content {
+		height: 36px;
+		align-items: center;
+	}
+
+	/* 复选框样式调整 */
+	.el-checkbox .el-checkbox__inner {
+		width: 18px;
+		height: 18px;
+		border-radius: 4px;
+	}
+
+	.el-checkbox__input.is-checked .el-checkbox__inner {
+		background-color: #10b981; /* 绿色勾选背景 */
+		border-color: #10b981;
+	}
+
+	/* 自定义图标样式 */
+	.tree-icon {
+		font-size: 18px;
+		&.checked {
+			color: #10b981; /* 绿色勾选图标 */
+		}
+		&.unchecked {
+			color: #c0c6cf; /* 未勾选灰色图标 */
+		}
+	}
 }
-</style>
+</style>