树形侧边栏(展开、全选、切换名称)

在这里插入图片描述

父文件: 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>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值