treeList.vue 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. <template>
  2. <div class="document-tree-container">
  3. <div class="document-tree-header">
  4. <span class="document-tree-title">题库归属</span>
  5. <el-button type="primary" size="small" @click="handleAddDocument">
  6. <el-icon><Plus /></el-icon>添加分类
  7. </el-button>
  8. </div>
  9. <el-tree
  10. ref="treeRef"
  11. :data="treeData"
  12. node-key="id"
  13. :props="defaultProps"
  14. default-expand-all
  15. highlight-current
  16. @node-click="handleNodeClick"
  17. >
  18. <template #default="{ node, data }">
  19. <div class="custom-tree-node">
  20. <div class="node-label">
  21. <el-icon><Folder /></el-icon>
  22. <span class="ml-2">{{ data.title }}</span>
  23. </div>
  24. <!-- <div class="node-actions" v-if="data.id">
  25. <el-button type="primary" link size="small" @click.stop="handleEdit(data)">
  26. <el-icon><Edit /></el-icon>
  27. </el-button>
  28. <el-button type="danger" link size="small" @click.stop="handleDelete(node, data)">
  29. <el-icon><Delete /></el-icon>
  30. </el-button>
  31. </div> -->
  32. </div>
  33. </template>
  34. </el-tree>
  35. </div>
  36. </template>
  37. <script lang="ts" setup>
  38. import { ref, defineProps, defineEmits } from 'vue';
  39. import { Plus, Folder, Edit, Delete } from '@element-plus/icons-vue';
  40. const props = defineProps({
  41. treeData: {
  42. type: Array,
  43. default: () => []
  44. }
  45. });
  46. const emit = defineEmits(['treeClick', 'updateDocument', 'deleteDocument']);
  47. const treeRef = ref(null);
  48. const defaultProps = {
  49. children: 'children',
  50. label: 'title'
  51. };
  52. // 处理节点点击
  53. const handleNodeClick = (data: any, node: any) => {
  54. // 获取当前节点的层级路径
  55. let currentNode = node;
  56. let firstLevelNode = null;
  57. let secondLevelNode = null;
  58. // 遍历父节点找到一级和二级节点
  59. while (currentNode) {
  60. if (currentNode.level === 1) {
  61. firstLevelNode = currentNode.data;
  62. } else if (currentNode.level === 2) {
  63. secondLevelNode = currentNode.data;
  64. }
  65. currentNode = currentNode.parent;
  66. }
  67. // 如果当前点击的是一级节点
  68. if (node.level === 1) {
  69. firstLevelNode = data;
  70. secondLevelNode = null;
  71. }
  72. // 如果当前点击的是二级节点
  73. else if (node.level === 2) {
  74. secondLevelNode = data;
  75. }
  76. emit('treeClick', {
  77. firstLevel: firstLevelNode,
  78. secondLevel: secondLevelNode,
  79. currentNode: data
  80. });
  81. };
  82. // 添加文档分类
  83. const handleAddDocument = () => {
  84. emit('updateDocument', 'add');
  85. };
  86. // 编辑文档分类
  87. const handleEdit = (data: any) => {
  88. emit('updateDocument', 'update', data);
  89. };
  90. // 删除文档分类
  91. const handleDelete = (node: any, data: any) => {
  92. emit('deleteDocument', data.id, () => {
  93. // 回调函数,删除成功后可以执行
  94. });
  95. };
  96. defineExpose({
  97. treeRef
  98. });
  99. </script>
  100. <style lang="scss" scoped>
  101. .document-tree-container {
  102. height: 100%;
  103. display: flex;
  104. flex-direction: column;
  105. }
  106. .document-tree-header {
  107. display: flex;
  108. justify-content: space-between;
  109. align-items: center;
  110. margin-bottom: 16px;
  111. }
  112. .document-tree-title {
  113. font-size: 16px;
  114. font-weight: bold;
  115. }
  116. .custom-tree-node {
  117. flex: 1;
  118. display: flex;
  119. align-items: center;
  120. justify-content: space-between;
  121. padding-right: 8px;
  122. }
  123. .node-label {
  124. display: flex;
  125. align-items: center;
  126. flex: 1;
  127. min-width: 0;
  128. position: relative;
  129. .ml-2 {
  130. overflow: hidden;
  131. white-space: nowrap;
  132. text-overflow: ellipsis;
  133. flex: 1;
  134. }
  135. }
  136. .node-actions {
  137. display: none;
  138. }
  139. .custom-tree-node:hover .node-actions {
  140. display: flex;
  141. overflow: hidden;
  142. white-space: nowrap;
  143. text-overflow: ellipsis;
  144. }
  145. </style>