uniapp 如何实现左右树形图布局

在uniapp中如何实现左右结构的树形图布局?目前需要在左侧展示树形菜单,右侧根据左侧选中的节点显示对应内容,类似于资源管理器的效果。尝试过使用uView等UI框架的树组件,但无法满足这种左右联动的需求。请问有没有成熟的解决方案或实现思路?最好能提供具体的代码示例或可参考的demo。

2 回复

使用flex布局,左侧固定宽度,右侧flex:1自适应。
左侧树形组件用u-tree,右侧内容区动态渲染。
监听左侧点击事件,更新右侧数据。
注意高度适配,可用calc(100vh - 顶部高度)。


在UniApp中实现左右树形图布局,可以通过以下步骤实现:

实现思路

  1. 使用Flex布局将页面分为左右两部分
  2. 左侧显示树形结构,右侧显示详情内容
  3. 通过点击左侧节点切换右侧显示内容

代码示例

<template>
  <view class="container">
    <!-- 左侧树形菜单 -->
    <scroll-view class="left-panel" scroll-y>
      <tree-menu 
        :data="treeData" 
        @node-click="handleNodeClick"
      />
    </scroll-view>
    
    <!-- 右侧内容区域 -->
    <view class="right-panel">
      <view v-if="selectedNode">
        <text class="node-title">{{ selectedNode.title }}</text>
        <text class="node-content">{{ selectedNode.content }}</text>
      </view>
      <view v-else class="placeholder">
        请选择左侧节点
      </view>
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      treeData: [
        {
          id: 1,
          title: '节点1',
          content: '节点1的详细内容',
          children: [
            {
              id: 11,
              title: '子节点1-1',
              content: '子节点1-1的详细内容'
            }
          ]
        },
        {
          id: 2,
          title: '节点2',
          content: '节点2的详细内容'
        }
      ],
      selectedNode: null
    }
  },
  methods: {
    handleNodeClick(node) {
      this.selectedNode = node
    }
  }
}
</script>

<style scoped>
.container {
  display: flex;
  height: 100vh;
}

.left-panel {
  width: 250rpx;
  background-color: #f5f5f5;
}

.right-panel {
  flex: 1;
  padding: 20rpx;
}

.node-title {
  font-size: 36rpx;
  font-weight: bold;
  margin-bottom: 20rpx;
  display: block;
}

.node-content {
  font-size: 28rpx;
  color: #666;
}

.placeholder {
  text-align: center;
  color: #999;
  margin-top: 200rpx;
}
</style>

树形组件(tree-menu.vue)

<template>
  <view class="tree-menu">
    <view 
      v-for="node in data" 
      :key="node.id"
      class="tree-node"
    >
      <view 
        class="node-item"
        @click="toggleNode(node)"
        :style="{ paddingLeft: (level * 20) + 'rpx' }"
      >
        <text v-if="node.children" class="arrow">
          {{ node.expanded ? '▼' : '▶' }}
        </text>
        <text class="node-text">{{ node.title }}</text>
      </view>
      
      <view v-if="node.children && node.expanded">
        <tree-menu 
          :data="node.children" 
          :level="level + 1"
          @node-click="$emit('node-click', $event)"
        />
      </view>
    </view>
  </view>
</template>

<script>
export default {
  name: 'tree-menu',
  props: {
    data: Array,
    level: {
      type: Number,
      default: 0
    }
  },
  methods: {
    toggleNode(node) {
      if (node.children) {
        this.$set(node, 'expanded', !node.expanded)
      } else {
        this.$emit('node-click', node)
      }
    }
  }
}
</script>

<style scoped>
.tree-node {
  line-height: 80rpx;
}

.node-item {
  display: flex;
  align-items: center;
  padding: 10rpx 0;
}

.arrow {
  margin-right: 10rpx;
  font-size: 24rpx;
}

.node-text {
  font-size: 28rpx;
}
</style>

关键点说明

  1. 使用Flex布局实现左右分栏
  2. 通过递归组件实现树形结构
  3. 使用scroll-view确保左侧菜单可滚动
  4. 通过事件传递实现左右联动

这样就能实现一个功能完整的左右树形图布局,支持节点展开/收起和内容联动显示。

回到顶部