HcTreeNode.vue 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. <template>
  2. <ElTree ref="ElTreeRef" :check-strictly="isStrictly" :data="ElTreeData" :expand-on-click-node="false"
  3. :indent="0" :node-key="nodeKey" :props="ElTreeProps" accordion
  4. class="hc-tree-node-box hc-tree-node tree-line" highlight-current show-checkbox @check="ElTreeCheckChange">
  5. <template #default="{ node, data }">
  6. <div class="custom-tree-node">
  7. <div class="label" @dblclick="ElTreeDblClick(data)">
  8. <el-input v-if="data.isInputName" v-model="data.title" size="small" @blur="ElTreeBtnClick(data)"
  9. @keyup="keyUpEvent($event,data)">
  10. <template #append>
  11. <el-button plain size="small" type="primary" @click="ElTreeBtnClick(data)">
  12. <HcIcon name="check"/>
  13. </el-button>
  14. </template>
  15. </el-input>
  16. <span v-else>{{ data.title }}</span>
  17. </div>
  18. </div>
  19. </template>
  20. </ElTree>
  21. </template>
  22. <script setup>
  23. import {nextTick, onMounted, ref, watch} from "vue";
  24. import {getArrValue} from "js-fast-way"
  25. import wbsApi from '~api/data-fill/wbs';
  26. //参数
  27. const props = defineProps({
  28. projectId: {
  29. type: [String, Number],
  30. default: ''
  31. },
  32. nodeKey: {
  33. type: String,
  34. default: 'primaryKeyId'
  35. },
  36. nodeId: {
  37. type: [String, Number],
  38. default: ''
  39. },
  40. oldId: {
  41. type: [String, Number],
  42. default: ''
  43. },
  44. strictly: {
  45. type: Boolean,
  46. default: false
  47. },
  48. })
  49. //变量
  50. const ElTreeRef = ref(null)
  51. const projectId = ref(props.projectId)
  52. const isStrictly = ref(props.strictly)
  53. const ElTreeProps = ref({label: 'title', children: 'children', isLeaf: 'notExsitChild'})
  54. //监听
  55. watch(() => [
  56. props.projectId,
  57. props.strictly,
  58. ], ([pid, strictly]) => {
  59. projectId.value = pid
  60. isStrictly.value = strictly
  61. })
  62. //渲染完成
  63. onMounted(() => {
  64. ElTreeLoadNode()
  65. })
  66. //事件
  67. const emit = defineEmits(['check-change'])
  68. //树形结构异步加载数据
  69. const ElTreeData = ref([])
  70. const ElTreeLoadNode = async () => {
  71. let nodeId = props.oldId || props.nodeId || ''
  72. const {error, code, data} = await wbsApi.queryWbsTreePrivateByProjectIdAndId({
  73. id: nodeId,
  74. projectId: projectId.value
  75. })
  76. if (!error && code === 200) {
  77. ElTreeData.value = getArrValue(data)
  78. await nextTick(() => {
  79. ElTreeCheckedKeys()
  80. })
  81. }
  82. }
  83. //被选择的
  84. const ElTreeCheckChange = (_, nodes) => {
  85. emit('check-change', nodes)
  86. }
  87. //处理节点
  88. const ElTreeCheckedKeys = () => {
  89. const Nodes = ElTreeRef.value.getCheckedNodes() || []
  90. const HalfNodes = ElTreeRef.value.getHalfCheckedNodes() || []
  91. emit('check-change', {
  92. checkedNodes: Nodes,
  93. halfCheckedNodes: HalfNodes
  94. })
  95. }
  96. //更改节点名称
  97. const ElTreeDblClick = (item) => {
  98. item.isInputName = true;
  99. }
  100. //回车
  101. const keyUpEvent = (e, item) => {
  102. if (e.key === "Enter") {
  103. ElTreeBtnClick(item)
  104. }
  105. }
  106. //更改节点名称完成
  107. const ElTreeBtnClick = (item) => {
  108. if (!item?.title) {
  109. window?.$message?.warning('节点名称不能为空')
  110. } else {
  111. item.isInputName = false;
  112. ElTreeCheckedKeys()
  113. }
  114. }
  115. </script>
  116. <style lang="scss" scoped>
  117. @import "../../../styles/app/tree.scss";
  118. .custom-tree-node {
  119. position: relative;
  120. width: 100%;
  121. }
  122. </style>
  123. <style lang="scss">
  124. .hc-tree-node-box .el-tree-node__content {
  125. height: 32px !important;
  126. }
  127. </style>