族谱也好,代码编辑器的文件结构也好,都是一棵树。

这两天写了一个树形结构的组件,基于一段JSON,在页面上渲染出树形结构,难点有二:

  1. 嵌套的结构
  2. 树枝的绘制

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+
分类: 未分类
浏览:2,062

0 条评论

发表评论

电子邮件地址不会被公开。

你必须允许浏览器启用JavaScript才能看到验证码

Scroll Up