tj
2025-06-05 bba272999cc546f65781bf3d20245a3f819af67f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
<template>
  <el-input
    v-model="selectedLabel"
    style="max-width: 600px"
    placeholder="请选择"
    class="input-with-select"
    :disabled="true"
    @click="handleClick"
  >
    <template #append>
      <el-button icon="Search" @click="handleClick" />
    </template>
  </el-input>
 
  <el-dialog title="选择节点" width="30%" @close="handleClose" v-model="dialogTableVisible" draggable overflow>
    <el-input v-model="filterText" style="width: 100%" placeholder="查找" />
    <el-tree
      ref="treeRef"
      :data="treeData"
      :props="treeProps"
      :show-checkbox="multiple"
      node-key="id"
      highlight-current
      @check-change="handleCheckChange"
      @node-click="handleNodeClick"
      :filter-node-method="filterNode"
      class="scrollable-tree"
      check-strictly="true"
    />
 
    <span slot="footer" class="dialog-footer">
      <el-button @click="handleCancel">取消</el-button>
      <el-button type="primary" @click="handleConfirm">确定</el-button>
    </span>
  </el-dialog>
</template>
 
<script setup>
import { ref, computed, watch, defineProps, defineEmits } from 'vue'
 
const props = defineProps({
  selectedNodes: {
    type: [Array, String], // Allow both array and string types
    default: () => [],
  },
  treeList: {
    type: Array,
    required: true,
  },
  idField: {
    type: String,
    default: 'id',
  },
  nameField: {
    type: String,
    default: 'name',
  },
  multiple: {
    type: Boolean,
    default: false,
  },
})
 
const emit = defineEmits(['update:selectedValue'])
 
const treeData = ref(props.treeList)
const selectedValue = ref(null)
const dialogTableVisible = ref(false)
const filterText = ref('')
const selectedLabel = ref('') // 新增变量
 
const treeProps = computed(() => ({
  children: 'children',
  label: props.nameField,
  value: props.idField,
}))
 
const treeRef = ref()
 
// 处理节点选中变化的方法
// 处理节点选中变化的方法
function handleCheckChange(checkedNodes, checkedKeys, node) {
  if (props.multiple) {
    // 多选模式
    const checkedNodes = treeRef.value.getCheckedNodes() // 获取所有选中的节点
    selectedValue.value = checkedNodes.map(node => node[props.idField]) // 更新选中的值
    selectedLabel.value = checkedNodes.map(node => node[props.nameField]).join(', ') // 更新选中的标签
  } else {
    // 单选模式
    // 直接使用传入的 checkedNodes 数组中的第一个节点
    const selectedNode = checkedNodes[0]
    selectedValue.value = selectedNode ? selectedNode[props.idField] : null // 更新选中的值
    selectedLabel.value = selectedNode ? selectedNode[props.nameField] : '' // 更新选中的标签
  }
}
 
function handleNodeClick(data) {
  if (!props.multiple) {
    // 单选模式
    selectedValue.value = data[props.idField] // 更新选中的值
    selectedLabel.value = data[props.nameField] // 更新选中的标签
    // dialogTableVisible.value = false; // 选择后关闭对话框
  } else {
    // 多选模式
    // 在多选模式下,选中的节点的处理一般在 handleCheckChange 中进行
    // 可以根据需要在这里添加其他逻辑
  }
}
 
function handleConfirm() {
  dialogTableVisible.value = false
  emitSelectedValue()
}
 
function handleCancel() {
  dialogTableVisible.value = false
}
 
function handleClose() {
  dialogTableVisible.value = false
}
 
function emitSelectedValue() {
  emit('update:selectedValue', selectedValue.value)
}
 
function handleClick() {
  filterText.value = ''
  dialogTableVisible.value = true
 
  console.log('aaaaaaaaaaaaa')
  console.log(treeData.value)
}
 
watch(
  () => props.treeList,
  newValue => {
    treeData.value = newValue
  },
)
 
watch(filterText, val => {
  treeRef.value.filter(val)
})
 
// watch(() => props.selectedNodes, (newValue) => {
//   if (treeRef.value) {
//     if (Array.isArray(newValue)) {
//       // 使用 el-tree 的 setCheckedKeys 方法来设置选中状态
//       treeRef.value.setCheckedKeys(newValue);
//       // 使用 el-tree 的 getCheckedNodes 方法来获取选中的节点
//       selectedLabel.value = treeRef.value.getCheckedNodes().map(node => node[props.nameField]).join(', ');
//     } else if (typeof newValue === 'string') {
//       // 使用 el-tree 的 setChecked 方法来设置选中状态
//       treeRef.value.setChecked(newValue, true); // 需要确保传递 true 参数来标记选中
//       const node = treeRef.value.getCheckedNodes().find(node => node[props.idField] === newValue);
//       selectedLabel.value = node ? node[props.nameField] : '';
//     }
//   }
// }, { immediate: true });
 
const filterNode = (value, data) => {
  if (!value) return true
  return data[props.nameField].includes(value)
}
 
// Return variables and methods to make them available in the template
</script>
<style scoped>
.scrollable-tree {
  min-height: 400px;
  max-height: 400px; /* Adjust this value to your desired height */
  overflow-y: auto;
}
</style>