父文件: index.vue
<template>
<div class="h-full p20px bg-#f5f5f5">
<ContentWrap class="w-260px h-[calc(100vh-200px)] min-h-700px">
<TenantTree @select="tentantSelect" />
</ContentWrap>
</div>
</template>
<script setup lang="ts">
import TenantTree from '../components/TenantTree/TenantTree.vue'
// 组织选择变化
const mutData = ref<String>('')
const tentantSelect = (data) => {
mutData.value = data?.join(',')
}
</script>
组件: TenantTree.vue
<script lang="ts" setup>
import { tenantTreeList4dict } from '@/api/common/dict'
import { propTypes } from '@/utils/propTypes'
import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
defineOptions({ name: 'TenantTree' })
const nodeKey = 'id'
const treeNodeAllFlag = ref<Boolean>(true)
const allShow = ref<Boolean>(true)
const shortName = ref<Boolean>(false)
const tenantTree = ref([])
const defaultProps = { children: 'children', label: 'tenantName' }
const treeRef = ref()
const mutData = ref<Array>([])
const { wsCache } = useCache()
const ROLE_ALIAS = wsCache.get(CACHE_KEY.ROLE_ALIAS)
const emit = defineEmits(['select'])
const checkChange = () => {
const all = getAllNodeKeys()
mutData.value = treeRef.value?.getCheckedKeys(false)
if (all.length !== mutData.value.length && mutData.value.length) {
emit('select', mutData.value)
}
}
// 获取组织
const getTenantTree = async () => {
try {
const { data = [] } = await tenantTreeList4dict()
tenantTree.value = data
await nextTick(async () => {
await handleCheckedTreeNodeAll()
mutData.value = treeRef.value?.getCheckedKeys(false)
})
} finally {
}
}
/** 展开/折叠全部 */
const handleTreeExpand = (type) => {
allShow.value = type
const nodes = treeRef.value?.store.nodesMap
for (let node in nodes) {
if (nodes[node].expanded === allShow.value) {
continue
}
nodes[node].expanded = allShow.value
}
}
/** 全选/全不选 */
const handleCheckedTreeNodeAll = async () => {
if (treeNodeAllFlag.value) {
await treeRef.value?.store.setCheckedKeys(getAllNodeKeys())
emit('select', mutData.value)
} else {
await treeRef.value?.store.setCheckedKeys([])
emit('select', mutData.value)
}
}
const getAllNodeKeys = () => {
let keys = []
tenantTree.value.forEach((node) => {
keys.push(node[nodeKey])
getAllChildNodeKeys(node, keys)
})
return keys
}
const getAllChildNodeKeys = (node, keys) => {
if (node.children) {
node.children.forEach((child) => {
keys.push(child[nodeKey])
getAllChildNodeKeys(child, keys)
})
}
}
onMounted(async () => {
const isSelectRole = ROLE_ALIAS.includes('selected')
if (!isSelectRole) {
getTenantTree()
} else {
emit('select', mutData.value)
}
})
</script>
<template>
<div class="font-size-14px pb-10px mb-10px border-b-1 border-b-solid border-b-color-#ccc">
<div class="bg-#cce1ff text-center line-height-30px mb10px">组织机构</div>
<div>
全选/清空:
<el-switch
v-model="treeNodeAllFlag"
active-text="是"
inactive-text="否"
inline-prompt
@change="handleCheckedTreeNodeAll"
/>
</div>
<div>
展开/折叠:
<el-switch v-model="allShow" active-text="展开" inactive-text="折叠" inline-prompt @change="handleTreeExpand" />
</div>
<div>
简称/全称:
<el-switch v-model="shortName" active-text="简称" inactive-text="全称" inline-prompt />
</div>
</div>
<div class="h-500px overflow-y-auto! mr-[-18px]">
<el-tree
ref="treeRef"
:data="tenantTree"
show-checkbox
:node-key="nodeKey"
default-expand-all
:props="defaultProps"
@check-change="checkChange"
indent="6"
:check-strictly="true"
accordion
>
<template #default="{ node, data }">
<span class="">
<el-text v-show="shortName" @click="console.log(data.shortName)" class="w-150px" truncated>
{{ data.shortName }}
</el-text>
<el-tooltip class="box-item" effect="dark" :content="node.label" placement="top" :show-after="500">
<el-text v-show="!shortName" @click="console.log(data.shortName)" class="w-150px" truncated>
{{ node.label }}
</el-text>
</el-tooltip>
</span>
</template>
</el-tree>
</div>
</template>