|
@@ -1,26 +1,41 @@
|
|
|
<template>
|
|
|
<div class="treeSelectV2">
|
|
|
- <el-popover placement="bottom" trigger="click" :teleported="false">
|
|
|
+ <el-popover placement="bottom" :visible="visiable" @hide="visiable = false" :teleported="false">
|
|
|
<template #reference>
|
|
|
- <el-input v-model="xzqdmName" readonly :disabled="disabled">
|
|
|
+ <el-input
|
|
|
+ v-model="labelName"
|
|
|
+ @input="onQueryFilter"
|
|
|
+ @mouseenter="mouseHandler(1)"
|
|
|
+ @mouseleave="mouseHandler(0)"
|
|
|
+ @click="clickHander"
|
|
|
+ :disabled="disabled"
|
|
|
+ :placeholder="placeholder"
|
|
|
+ >
|
|
|
<template #suffix>
|
|
|
- <el-icon><ArrowDown /></el-icon>
|
|
|
+ <el-icon v-if="labelName && isHover">
|
|
|
+ <CircleClose @click="clearHandler" />
|
|
|
+ </el-icon>
|
|
|
+ <el-icon :class="{ rotate: isRotate }" v-else>
|
|
|
+ <ArrowDown />
|
|
|
+ </el-icon>
|
|
|
</template>
|
|
|
</el-input>
|
|
|
</template>
|
|
|
<template #default>
|
|
|
- <template v-if="filterMethod != null">
|
|
|
- <el-input v-model="filterName" @input="onQueryFilter" style="margin-bottom: 10px" />
|
|
|
- </template>
|
|
|
<el-tree-v2
|
|
|
ref="treeRef"
|
|
|
- @node-click="nodeClickHandle"
|
|
|
+ highlight-current
|
|
|
style="width: 100%"
|
|
|
:filter-method="filterMethod"
|
|
|
:props="props"
|
|
|
:data="data"
|
|
|
- :render-after-expand="expend"
|
|
|
- />
|
|
|
+ :expand-on-click-node="false"
|
|
|
+ @node-click="nodeClickHandle"
|
|
|
+ >
|
|
|
+ <template v-if="$slots.default" #default="{ node }">
|
|
|
+ <slot :node="node"></slot>
|
|
|
+ </template>
|
|
|
+ </el-tree-v2>
|
|
|
</template>
|
|
|
</el-popover>
|
|
|
</div>
|
|
@@ -33,34 +48,97 @@ import { ArrowDown } from '@element-plus/icons-vue'
|
|
|
defineOptions({
|
|
|
name: 'TreeSelectV2'
|
|
|
})
|
|
|
-const $props = defineProps<
|
|
|
- Partial<{
|
|
|
- data: any[]
|
|
|
- modelValue: string | number
|
|
|
- props: any
|
|
|
- disabled: boolean
|
|
|
- expend: boolean
|
|
|
- filterMethod: any
|
|
|
- }>
|
|
|
->()
|
|
|
+const $props = withDefaults(
|
|
|
+ defineProps<
|
|
|
+ Partial<{
|
|
|
+ data: any[]
|
|
|
+ modelValue: string | number
|
|
|
+ props: any
|
|
|
+ disabled: boolean
|
|
|
+ expend: boolean
|
|
|
+ filterMethod: any
|
|
|
+ placeholder: string
|
|
|
+ }>
|
|
|
+ >(),
|
|
|
+ {
|
|
|
+ props: {
|
|
|
+ label: 'label',
|
|
|
+ value: 'value',
|
|
|
+ children: 'children'
|
|
|
+ },
|
|
|
+ expend: true,
|
|
|
+ placeholder: '请选择'
|
|
|
+ }
|
|
|
+)
|
|
|
const $emit = defineEmits<{
|
|
|
(e: 'update:modelValue', v: any): void
|
|
|
}>()
|
|
|
-const xzqdmName = ref<string>()
|
|
|
-const filterName = ref<string>()
|
|
|
-
|
|
|
+const visiable = ref<boolean>(false)
|
|
|
+const isRotate = ref<boolean>(false)
|
|
|
+const labelName = ref<string>('')
|
|
|
+const isHover = ref<boolean>(false)
|
|
|
+const mouseHandler = (type: number) => {
|
|
|
+ isHover.value = type === 1 ? true : false
|
|
|
+}
|
|
|
+const clickHander = () => {
|
|
|
+ visiable.value = !visiable.value
|
|
|
+}
|
|
|
+const clearHandler = () => {
|
|
|
+ nodeClickHandle({
|
|
|
+ [$props.props['value'] ?? 'value']: '',
|
|
|
+ [$props.props['label'] ?? 'label']: ''
|
|
|
+ })
|
|
|
+ onQueryFilter('')
|
|
|
+}
|
|
|
+watch(visiable, () => {
|
|
|
+ isRotate.value = visiable.value ? true : false
|
|
|
+})
|
|
|
const treeRef = ref<InstanceType<typeof ElTreeV2>>()
|
|
|
const onQueryFilter = (query: string) => {
|
|
|
treeRef.value!.filter(query)
|
|
|
}
|
|
|
const nodeClickHandle = (data) => {
|
|
|
- xzqdmName.value = data['name']
|
|
|
- $emit('update:modelValue', data['id'])
|
|
|
+ visiable.value = false
|
|
|
+ labelName.value = data[$props.props['label'] ?? 'label']
|
|
|
+ $emit('update:modelValue', data[$props.props['value'] ?? 'value'])
|
|
|
+}
|
|
|
+const getExpandedIds = (nodes?: any[]) => {
|
|
|
+ if (nodes && nodes.length === 0) return []
|
|
|
+ const ids: any[] = []
|
|
|
+ function getIdByDfs(nodes) {
|
|
|
+ for (let i = 0; i < nodes.length; i++) {
|
|
|
+ const node = nodes[i]
|
|
|
+ if (
|
|
|
+ !node[$props.props['children'] ?? 'children'] ||
|
|
|
+ node[$props.props['children'] ?? 'children'].length == 0
|
|
|
+ )
|
|
|
+ break
|
|
|
+ ids.push(node[$props.props['value'] ?? 'value'])
|
|
|
+ if (
|
|
|
+ node[$props.props['children'] ?? 'children'] &&
|
|
|
+ node[$props.props['children'] ?? 'children'].length > 0
|
|
|
+ ) {
|
|
|
+ getIdByDfs(node[$props.props['children'] ?? 'children'])
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ getIdByDfs(nodes)
|
|
|
+ return ids
|
|
|
+}
|
|
|
+const setExpandedKeys = async () => {
|
|
|
+ await nextTick()
|
|
|
+ const allChooseIds = getExpandedIds($props.data)
|
|
|
+ treeRef.value?.setExpandedKeys(allChooseIds)
|
|
|
}
|
|
|
+watchEffect(() => {
|
|
|
+ if ($props.data && $props.expend) {
|
|
|
+ setExpandedKeys()
|
|
|
+ }
|
|
|
+})
|
|
|
watchEffect(() => {
|
|
|
const item = treeRef.value?.getNode($props.modelValue)
|
|
|
if (item) {
|
|
|
- xzqdmName.value = item['label']
|
|
|
+ labelName.value = item['label'] as string
|
|
|
}
|
|
|
})
|
|
|
</script>
|
|
@@ -84,8 +162,16 @@ watchEffect(() => {
|
|
|
}
|
|
|
:deep(.is-focus) {
|
|
|
.el-input__suffix .el-icon {
|
|
|
- transform: rotateZ(-180deg);
|
|
|
cursor: pointer;
|
|
|
+ transform: rotateZ(0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .rotate {
|
|
|
+ transform: rotateZ(-180deg) !important;
|
|
|
+ }
|
|
|
+ :deep(.el-tree-node__content) {
|
|
|
+ .is-leaf {
|
|
|
+ flex-shrink: 0;
|
|
|
}
|
|
|
}
|
|
|
}
|