<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>
|