族谱也好,代码编辑器的文件结构也好,都是一棵树。
这两天写了一个树形结构的组件,基于一段JSON,在页面上渲染出树形结构,难点有二:
- 嵌套的结构
- 树枝的绘制
JsonUnit.vue
<template>
<div class="json-unit">
<div class="line-vertical" :class="{ special: index === brotherNum - 1 }"></div>
<div class="json-row">
<div v-if="depth !== 0" class="line-horizontal"></div>
<div class="item">辈分: {{ depth + 1 }}</div>
<div class="item">家中排名: {{ index + 1 }}</div>
<div class="item">名称: {{ jsonData.key }}</div>
</div>
<JsonUnit :json-data="item" :depth="depth + 1" :index="index" :brother-num="jsonData.children.length" v-for="(item, index) in jsonData.children" :key="index" />
</div>
</template>
<script lang="ts">
export default {
name: 'JsonUnit',
}
</script>
<script setup lang="ts">
import { withDefaults, ref } from 'vue'
const props = withDefaults(defineProps<{
jsonData: Record<string, any> // 族谱
depth: number // 辈分
index: number // 家中排名
brotherNum: number // 兄弟个数
}>(), {
jsonData: () => ({}),
depth: 0,
index: 0,
brotherNum: 0
})
</script>
<style lang="stylus" scoped>
.json-unit {
margin-left: 0;
.json-unit {
position: relative;
margin-left: 26px;
}
.line-vertical {
position: absolute;
left: -13px; // 26/2
bottom: 15px;
width: 0;
height: calc(100% + 10px);
border-left: 1px solid #d9d9d9;
z-index: 1;
&.special {
top: -25px; // -(10+16-1)
height: 42px; // 10+32
}
}
.json-row {
position: relative;
display: flex;
box-sizing: border-box;
height: 32px;
line-height: 32px;
padding: 0 10px;
border: 1px solid #d9d9d9;
margin-top: 10px;
background-color: #fff;
z-index: 2;
.line-horizontal {
position: absolute;
left: -13px;
bottom: 14px;
width: 13px;
height: 0;
border-bottom: 1px solid #d9d9d9;
}
.item {
margin-right: 20px;
}
}
}
</style>
使用
<template>
<JsonUnit :json-data="item" :brother-num="jsonData.length" v-for="(item, index) in jsonData" :key="index" />
</template>
<script setup lang="ts">
import JsonUnit from './JsonUnit.vue'
const jsonData = [{
key: '1',
children: [{
key: '1-1',
children: [{
key: '1-1-1',
children: [{
key: '1-1-1-1',
children: [{
key: '1-1-1-1-1'
}, {
key: '1-1-1-1-2',
children: [{
key: '1-1-1-1-2-1'
}, {
key: '1-1-1-1-2-2',
children: [{
key: '1-1-1-1-2-2-1',
children: [{
key: '1-1-1-1-2-2-1-1'
}, {
key: '1-1-1-1-2-2-1-2',
children: [{
key: '1-1-1-1-2-2-1-2-1'
}, {
key: '1-1-1-1-2-2-1-2-2'
}, {
key: '1-1-1-1-2-2-1-2-3'
}],
}],
}, {
key: '1-1-1-1-2-2-2',
children: [{
key: '1-1-1-1-2-2-2-1'
}, {
key: '1-1-1-1-2-2-2-2'
}],
}]
}, {
key: '1-1-1-1-2-2-3'
}],
}],
}, {
key: '1-1-1-2',
children: [{
key: '1-1-1-2-1'
}, {
key: '1-1-1-2-2'
}],
}]
}, {
key: '1-1-2',
children: [{
key: '1-1-2-1'
}, {
key: '1-1-2-2'
}, {
key: '1-1-2-3'
}],
}],
}, {
key: '1-2',
children: [{
key: '1-2-1'
}, {
key: '1-2-2'
}],
}, {
key: '1-2-1'
}]
}]
</script>
1+
0 条评论