0
点赞
收藏
分享

微信扫一扫

Node.js入门指南(五)

我是小瘦子哟 2023-12-04 阅读 51

在这里插入图片描述
创建组件名称 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>

举报

相关推荐

0 条评论