创建组件名称 TreeNodeView.vue
<template><div class="tree-node"><div class="node">{{ rootNodeName }}</div><div class="children" :style="childrenLineStyle"><div class="child-node" v-for="node in childNodes" :key="node.id"><div class="node">{{ node.name }}</div></div></div></div>
</template><script setup>
import {computed, ref, onMounted} from 'vue';const props = defineProps({childNodes: {type: Array,required: true},rootNodeName: {type: String,required: true,},
});const childNode = ref(null);
const childrenWidth = ref(null);
const childrenMarginLeft = ref(null);const childrenLineStyle = computed(() => {if (!childNode.value) {return {};}const getWidth = (element) => {const style = getComputedStyle(element);return parseFloat(style.width) + parseFloat(style.marginLeft) + parseFloat(style.marginRight);};let allNodeWidth = Array.from(childNode.value).reduce((total, node) => total + getWidth(node), 0);const firstNodeWidth = getWidth(childNode.value[0]) / 2;let lastNodeWidth = 0;if (childNode.value.length > 1) {lastNodeWidth = getWidth(childNode.value[childNode.value.length - 1]) / 2;}childrenWidth.value = `${allNodeWidth - firstNodeWidth - lastNodeWidth}px`;childrenMarginLeft.value = `${firstNodeWidth}px`;return {};
});onMounted(() => {childNode.value = document.querySelectorAll('.child-node');
});
</script><style>
.tree-node {display: inline-flex;flex-direction: column;align-items: center;
}.node {border: 1px solid #000;padding: 5px;position: relative;
}.children {display: flex;justify-content: center;position: relative;margin-top: 45px;
}.children::before {content: '';height: 25px;border: 0.00001rem solid #000;position: absolute;top: -46px;
}.child-node {position: relative;margin-left: 10px;margin-right: 10px;
}.child-node::before {content: '';position: absolute;top: -20px;left: 50%;transform: translateX(-50%);height: 20px;border-left: 1px solid #000;
}.children::after {content: '';position: absolute;top: -20px;left: 0;right: 0;border-top: 1px solid #000;width: v-bind(childrenWidth);margin-left: v-bind(childrenMarginLeft);
}
</style>
<template><div class="tree-node"><TreeNodeView v-bind="nodeViewConfig"></TreeNodeView></div>
</template><script setup>
import TreeNodeView from "./components/TreeNodeView.vue";const nodeViewConfig = {rootNodeName: '根节点',childNodes: [{id: 1, name: '节点1-1'},{id: 2, name: '节点222222221-2'},{id: 3, name: '节点1-3'},{id: 4, name: '节点1-4222222'},{id: 5, name: '节点1-4'},{id: 6, name: '节点1-4'}]
}
</script><style scoped></style>