当前位置:首页 > VUE

vue实现树形控件

2026-02-20 06:15:57VUE

Vue 实现树形控件的方法

使用递归组件实现基础树形结构

递归组件是 Vue 中实现树形结构的核心方法。通过组件调用自身,可以动态渲染嵌套的树节点数据。

<template>
  <div class="tree-node">
    <div @click="toggle">{{ node.name }}</div>
    <div v-show="isOpen" v-if="node.children">
      <tree-node 
        v-for="child in node.children" 
        :key="child.id" 
        :node="child"
      />
    </div>
  </div>
</template>

<script>
export default {
  name: 'TreeNode',
  props: {
    node: Object
  },
  data() {
    return {
      isOpen: false
    }
  },
  methods: {
    toggle() {
      this.isOpen = !this.isOpen
    }
  }
}
</script>

使用第三方组件库快速实现

Element UI、Ant Design Vue 等流行 UI 库都提供了成熟的树形控件实现。

安装 Element UI:

npm install element-ui

使用示例:

<template>
  <el-tree
    :data="treeData"
    :props="defaultProps"
    @node-click="handleNodeClick"
  />
</template>

<script>
export default {
  data() {
    return {
      treeData: [{
        label: '一级节点',
        children: [{
          label: '二级节点'
        }]
      }],
      defaultProps: {
        children: 'children',
        label: 'label'
      }
    }
  },
  methods: {
    handleNodeClick(data) {
      console.log(data)
    }
  }
}
</script>

实现可拖拽的树形结构

通过引入拖拽库实现节点拖拽排序功能。

vue实现树形控件

使用 sortablejs 实现:

npm install sortablejs

实现代码:

<template>
  <div ref="tree">
    <tree-node 
      v-for="node in treeData" 
      :key="node.id" 
      :node="node"
    />
  </div>
</template>

<script>
import Sortable from 'sortablejs'
export default {
  mounted() {
    this.setSortable()
  },
  methods: {
    setSortable() {
      new Sortable(this.$refs.tree, {
        handle: '.drag-handle',
        animation: 150,
        onEnd: this.onSortEnd
      })
    },
    onSortEnd(evt) {
      // 处理排序后的数据更新
    }
  }
}
</script>

实现树节点的增删改查功能

为树形控件添加完整的 CRUD 操作功能。

vue实现树形控件

<template>
  <div>
    <el-tree
      ref="tree"
      :data="treeData"
      node-key="id"
      default-expand-all
    />
    <el-button @click="addNode">添加节点</el-button>
    <el-button @click="removeNode">删除节点</el-button>
  </div>
</template>

<script>
export default {
  methods: {
    addNode() {
      const newNode = { id: Date.now(), label: '新节点' }
      this.$refs.tree.append(newNode, this.$refs.tree.getCurrentNode())
    },
    removeNode() {
      this.$refs.tree.remove(this.$refs.tree.getCurrentNode())
    }
  }
}
</script>

实现树节点的懒加载

对于大数据量的树形结构,实现按需加载子节点。

<template>
  <el-tree
    :props="props"
    :load="loadNode"
    lazy
  />
</template>

<script>
export default {
  data() {
    return {
      props: {
        label: 'name',
        children: 'zones',
        isLeaf: 'leaf'
      }
    }
  },
  methods: {
    loadNode(node, resolve) {
      if (node.level === 0) {
        // 加载根节点
        return resolve([{ name: '根节点' }])
      }
      if (node.level > 3) {
        // 设置叶子节点
        return resolve([])
      }
      // 模拟异步加载
      setTimeout(() => {
        resolve([{
          name: '子节点' + node.level
        }])
      }, 500)
    }
  }
}
</script>

实现树形表格

结合表格展示树形数据,实现更复杂的数据展示需求。

<template>
  <el-table
    :data="tableData"
    row-key="id"
    default-expand-all
    :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
  >
    <el-table-column prop="date" label="日期"></el-table-column>
    <el-table-column prop="name" label="名称"></el-table-column>
  </el-table>
</template>

<script>
export default {
  data() {
    return {
      tableData: [{
        id: 1,
        date: '2023-01-01',
        name: '一级',
        children: [{
          id: 2,
          date: '2023-01-02',
          name: '二级'
        }]
      }]
    }
  }
}
</script>

实现树形选择器

将树形结构封装为选择器组件,方便表单使用。

<template>
  <el-popover
    ref="popover"
    placement="bottom-start"
    trigger="click"
  >
    <el-tree
      :data="treeData"
      :props="defaultProps"
      @node-click="handleNodeClick"
    />
    <el-input
      slot="reference"
      v-model="selectedLabel"
      readonly
      placeholder="请选择"
    />
  </el-popover>
</template>

<script>
export default {
  data() {
    return {
      selectedLabel: '',
      treeData: [/* 树数据 */],
      defaultProps: {
        children: 'children',
        label: 'label'
      }
    }
  },
  methods: {
    handleNodeClick(data) {
      this.selectedLabel = data.label
      this.$refs.popover.doClose()
    }
  }
}
</script>

标签: 控件vue
分享给朋友:

相关文章

vue实现骰子

vue实现骰子

Vue 实现骰子功能 创建 Vue 组件 在 Vue 项目中创建一个骰子组件,例如 Dice.vue。该组件包含骰子的外观和逻辑。 <template> <div class=…

vue实现RTMP

vue实现RTMP

Vue 中实现 RTMP 流播放 RTMP(Real-Time Messaging Protocol)是一种用于实时音视频流传输的协议。在 Vue 中实现 RTMP 播放通常需要借助第三方库或播放器。…

vue实现 hover

vue实现 hover

实现 Vue 中的 hover 效果 在 Vue 中实现 hover 效果可以通过多种方式完成,以下是常见的几种方法: 使用 CSS 伪类 最简单的方式是直接使用 CSS 的 :hover 伪类,无…

vue 实现长按

vue 实现长按

实现长按功能的基本思路 在Vue中实现长按功能,通常需要监听元素的mousedown或touchstart事件,启动一个计时器。当用户按住元素超过设定的时间阈值时,触发长按回调函数。如果在时间阈值内触…

vue实现 弹窗

vue实现 弹窗

Vue 实现弹窗的基本方法 使用 Vue 实现弹窗可以通过多种方式,包括组件化、指令、插件等。以下是几种常见的实现方法。 组件化实现弹窗 创建一个独立的弹窗组件,通过 props 控制显示与隐藏。…

vue广播实现

vue广播实现

vue广播实现 在Vue中实现广播功能可以通过事件总线(Event Bus)或Vuex来完成。以下是两种常见的实现方式: 使用事件总线(Event Bus) 事件总线是一种简单的跨组件通信方式,适用…