当前位置:首页 > VUE

vue实现可选菜单树

2026-02-24 10:03:14VUE

Vue 实现可选菜单树

使用 Element UI 的 Tree 组件

Element UI 提供了 Tree 组件,支持复选框功能,可以直接用于实现可选菜单树。安装 Element UI 后,在 Vue 项目中引入 Tree 组件。

<template>
  <el-tree
    :data="menuData"
    show-checkbox
    node-key="id"
    :default-expanded-keys="[2, 3]"
    :default-checked-keys="[5]"
    :props="defaultProps"
  >
  </el-tree>
</template>

<script>
export default {
  data() {
    return {
      menuData: [
        {
          id: 1,
          label: '一级菜单',
          children: [
            {
              id: 2,
              label: '二级菜单',
              children: [
                { id: 3, label: '三级菜单' },
                { id: 4, label: '三级菜单' }
              ]
            },
            {
              id: 5,
              label: '二级菜单',
              children: [
                { id: 6, label: '三级菜单' },
                { id: 7, label: '三级菜单' }
              ]
            }
          ]
        }
      ],
      defaultProps: {
        children: 'children',
        label: 'label'
      }
    };
  }
};
</script>

自定义递归组件实现菜单树

如果需要更灵活的控制,可以自定义递归组件实现菜单树。创建一个递归组件,支持复选框选择功能。

<template>
  <div>
    <tree-node
      v-for="node in treeData"
      :key="node.id"
      :node="node"
      @toggle-check="handleCheck"
    />
  </div>
</template>

<script>
import TreeNode from './TreeNode.vue';

export default {
  components: { TreeNode },
  data() {
    return {
      treeData: [
        {
          id: 1,
          label: '一级菜单',
          checked: false,
          children: [
            {
              id: 2,
              label: '二级菜单',
              checked: false,
              children: [
                { id: 3, label: '三级菜单', checked: false },
                { id: 4, label: '三级菜单', checked: false }
              ]
            }
          ]
        }
      ]
    };
  },
  methods: {
    handleCheck(nodeId) {
      const updateNode = (nodes) => {
        nodes.forEach(node => {
          if (node.id === nodeId) {
            node.checked = !node.checked;
          }
          if (node.children) {
            updateNode(node.children);
          }
        });
      };
      updateNode(this.treeData);
    }
  }
};
</script>

创建 TreeNode.vue 组件:

<template>
  <div>
    <div>
      <input
        type="checkbox"
        :checked="node.checked"
        @change="$emit('toggle-check', node.id)"
      />
      {{ node.label }}
    </div>
    <div v-if="node.children" style="margin-left: 20px">
      <tree-node
        v-for="child in node.children"
        :key="child.id"
        :node="child"
        @toggle-check="$emit('toggle-check', $event)"
      />
    </div>
  </div>
</template>

<script>
export default {
  name: 'TreeNode',
  props: {
    node: {
      type: Object,
      required: true
    }
  }
};
</script>

使用第三方库 Vue-Tree-Select

Vue-Tree-Select 是一个专门用于树形选择菜单的库,支持单选、多选、搜索等功能。安装后可以直接使用。

npm install vue-tree-select

在 Vue 项目中使用:

<template>
  <vue-tree-select
    :options="treeOptions"
    :value="selectedNodes"
    @select="handleSelect"
    multiple
  />
</template>

<script>
import VueTreeSelect from 'vue-tree-select';

export default {
  components: { VueTreeSelect },
  data() {
    return {
      treeOptions: [
        {
          id: 1,
          label: '一级菜单',
          children: [
            {
              id: 2,
              label: '二级菜单',
              children: [
                { id: 3, label: '三级菜单' },
                { id: 4, label: '三级菜单' }
              ]
            }
          ]
        }
      ],
      selectedNodes: []
    };
  },
  methods: {
    handleSelect(selectedNodes) {
      this.selectedNodes = selectedNodes;
    }
  }
};
</script>

父子节点联动选中

实现父子节点联动选中功能,可以在自定义递归组件中添加逻辑,选中父节点时自动选中所有子节点,或取消子节点时检查父节点状态。

methods: {
  handleCheck(nodeId) {
    const updateNode = (nodes) => {
      nodes.forEach(node => {
        if (node.id === nodeId) {
          node.checked = !node.checked;
          if (node.children) {
            this.toggleChildren(node.children, node.checked);
          }
        }
        if (node.children) {
          updateNode(node.children);
        }
      });
    };
    updateNode(this.treeData);
  },
  toggleChildren(children, checked) {
    children.forEach(child => {
      child.checked = checked;
      if (child.children) {
        this.toggleChildren(child.children, checked);
      }
    });
  }
}

获取选中节点数据

通过遍历树数据,收集所有选中节点的 ID 或完整数据,用于提交或进一步处理。

methods: {
  getCheckedNodes() {
    const checkedNodes = [];
    const traverse = (nodes) => {
      nodes.forEach(node => {
        if (node.checked) {
          checkedNodes.push(node);
        }
        if (node.children) {
          traverse(node.children);
        }
      });
    };
    traverse(this.treeData);
    return checkedNodes;
  }
}

动态加载节点数据

对于大型菜单树,可以动态加载子节点数据以减少初始加载时间。在节点展开时加载子节点数据。

methods: {
  loadNode(node, resolve) {
    if (node.level === 0) {
      resolve([{ id: 1, label: '一级菜单' }]);
    } else {
      setTimeout(() => {
        resolve([
          { id: 2, label: '二级菜单' },
          { id: 3, label: '二级菜单' }
        ]);
      }, 500);
    }
  }
}

在 Element UI 的 Tree 组件中使用:

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

通过以上方法,可以实现灵活且功能丰富的可选菜单树,满足不同场景的需求。

vue实现可选菜单树

标签: 可选菜单
分享给朋友:

相关文章

vue实现菜单搜索

vue实现菜单搜索

实现思路 在Vue中实现菜单搜索功能,通常需要结合输入框的实时监听、菜单数据的过滤以及结果的动态展示。核心逻辑包括监听用户输入、过滤菜单数据、高亮匹配关键词。 基本实现步骤 创建搜索输入框 在模板中…

vue实现左侧菜单

vue实现左侧菜单

实现左侧菜单的基本结构 在Vue中实现左侧菜单通常需要结合组件化思想和路由功能。使用<el-menu>组件(Element UI)或自定义组件搭配Vue Router是常见方案。 &l…

js实现菜单导航

js实现菜单导航

实现基础菜单导航结构 使用HTML和CSS创建菜单的基本结构,再通过JavaScript添加交互功能。HTML部分通常使用<ul>和<li>标签构建层级: <nav i…

vue实现菜单联动

vue实现菜单联动

实现菜单联动的基本思路 在Vue中实现菜单联动通常涉及父子组件通信或状态管理。核心是通过数据绑定和事件监听,确保一个菜单的选择能触发另一个菜单的更新。 数据准备与结构设计 定义菜单数据时,建议使用…

vue实现菜单切换

vue实现菜单切换

Vue 实现菜单切换的方法 在 Vue 中实现菜单切换通常涉及动态绑定类名、条件渲染或状态管理。以下是几种常见的方法: 动态绑定 class 实现高亮切换 通过 v-bind:class 动态绑定类…

vue实现级联菜单

vue实现级联菜单

实现级联菜单的基本思路 Vue中实现级联菜单通常需要以下关键点:数据结构的组织、组件间的通信、动态渲染子菜单。一般采用递归组件或逐层渲染的方式实现。 数据结构设计 级联菜单的数据通常为嵌套结构,例…