vue 树形结构展示
参考文档:https://blog.csdn.net/weixin_44326389/article/details/118613647
1、效果图
2、代码
子组件
点击查看代码
<template>
<div id="tree">
<div class="checkThem" >
<div v-for="item in treeList" :key="item.id">
<!-- 一级的 -->
<div class="check_checkThem_first flex-h flex-vh-center">
<div class="tree_name" >
<span>{{ item.userName }}-{{item.orgName}}</span>
<div v-if="item.userName" class="tag_box">
<nut-tag color="#12BB82" v-if="item.currentProgress == '已完成'">{{ item.currentProgress
}}</nut-tag>
<nut-tag color="#999999" v-else-if="item.currentProgress == '未完成'">{{ item.currentProgress
}}</nut-tag>
<nut-tag color="#ED522F" v-else>{{ item.currentProgress }}</nut-tag>
</div>
</div>
<div v-if="!item.userName && item.childrenList.length > 0">
<div class="open_img click_img" v-show="showFlagList[item.orgCode]"
@click.stop="handleChack('up', item)">
<img src="@/assets/images/up.png" alt="">
</div>
<div class="down_img click_img" v-show="!showFlagList[item.orgCode]"
@click.stop="handleChack('down', item)">
<img src="@/assets/images/down.png" alt="">
</div>
</div>
<!-- 二级的 -->
<div :class="'tree_level' + item.level" class="check_checkThem_second flex-h flex-vh-center"
v-show="showFlagList[item.orgCode] && item.childrenList && JSON.stringify(item.childrenList) != '[]'">
<TaskTree :treeList="item.childrenList"></TaskTree>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { defineProps, reactive } from 'vue'
import { useRouter } from 'vue-router';
import store from '@/store'
const props = defineProps(['treeList', 'searchName'])
const $router = useRouter();
const showFlagList = reactive({})
const handleChack = (falg, item) => {
//点击
if (falg === 'down') {
//展开
showFlagList[item.orgCode] = true
} else {
//关闭
showFlagList[item.orgCode] = false
}
}
</script>
<style lang="scss" scoped>
$padLeft: 20px;
.check_checkThem_first {
position: relative;
min-height: 48px;
line-height: 48px;
.tree_name {
width: 100%;
display: inline-block;
border-bottom: 1px solid #ECECEC;
box-sizing: border-box;
.tree_img {
width: 16px;
height: 18px;
margin-right: 4px;
vertical-align: middle;
}
}
}
.tree_level1 {
.tree_name {
padding-left: $padLeft * 1;
}
}
.tree_level2 {
.tree_name {
padding-left: $padLeft * 2;
}
}
.tree_level3 {
.tree_name {
padding-left: $padLeft * 3;
}
}
.tree_level4 {
.tree_name {
padding-left: $padLeft * 4;
}
}
.tree_level5 {
.tree_name {
padding-left: $padLeft * 5;
}
}
.tree_level6 {
.tree_name {
padding-left: $padLeft * 6;
}
}
.tree_level7 {
.tree_name {
padding-left: $padLeft * 7;
}
}
.tree_level8 {
.tree_name {
padding-left: $padLeft * 8;
}
}
.tree_level9 {
.tree_name {
padding-left: $padLeft * 9;
}
}
.tree_level10 {
.tree_name {
padding-left: $padLeft * 10;
}
}
.tree_level11 {
.tree_name {
padding-left: $padLeft * 11;
}
}
.click_img {
position: absolute;
right: 0;
top: 0;
}
.open_img {
width: 12px;
height: 12px;
margin-right: 2%;
img {
width: 100%;
}
}
.down_img {
width: 12px;
height: 16px;
margin-right: 2%;
img {
width: 100%;
}
}
.tag_box {
.nut-tag {
position: absolute;
right: 0;
top: calc(50% - 10px);
min-width: 38px;
height: 16px;
opacity: 1;
border-radius: 4px;
display: flex;
justify-content: center;
font-size: 10px;
color: #fff;
}
}
</style>
2、父组件
点击查看代码
<template>
<div class="check_content">
<div class="list_box">
<TaskTree :treeList="treeList" :searchName="queryData.userName"></TaskTree>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, reactive } from 'vue';
import TaskTree from '@/components/TaskTree'
import { assignmentCheckPerson } from '@/axios/index'
import { useRoute } from 'vue-router';
import dayjs from 'dayjs';
const $route = useRoute();
onMounted(() => {
queryData = $route.query
getList()
})
const isVisible = ref(false)
let queryData = reactive({
orgCode: '',
startDate: '',
endDate: '',
userName: ''
})
const treeList = ref([])//一级查询总数据
const getList = () => {
queryData.userName = searchValue.value
queryData.startDate = dateTimeStr.value
queryData.endDate = dateTimeStr.value
assignmentCheckPerson(queryData).then((response) => {
renderTree(response.data, 1)
treeList.value = response.data
})
}
// 数据处理成自己需要的结构
const renderTree = (data, level) => {
return data.map((item) => {
item.level = level;
if(!item.childrenList || JSON.stringify(item.childrenList) == '[]'){
item.childrenList=[]
}
if(!item.userProgressVOList || JSON.stringify(item.userProgressVOList) == '[]'){
item.userProgressVOList=[]
}
// console.log(item.childrenList,item.userProgressVOList);
item.childrenList = item.childrenList.concat([...item.userProgressVOList])
renderTree(item.childrenList, level + 1);
});
};
</script>
<style scoped lang='scss'>
.list_box {
margin: 0 16px;
}
</style>