Element UI框架中巧用树选择器的实现

一、Element UI框架中巧用树选择器的实现

Element UI是一个基于Vue.js的开源组件库,提供了丰富、实用的UI组件,其中树选择器是常用的组件之一。本文将介绍如何巧用树选择器实现多级联动菜单的效果。

二、树选择器的基本用法

在Element UI中,要使用树选择器需要引入以下组件:

<template>
  <el-tree :data="data" show-checkbox node-key="id"></el-tree>
</template>

<script>
  export default {
    data() {
      return {
        data: [
          {
            id: 1,
            label: 'Level one 1',
            children: [
              {
                id: 4,
                label: 'Level two 1-1',
                children: [
                  {
                    id: 9,
                    label: 'Level three 1-1-1'
                  },
                  {
                    id: 10,
                    label: 'Level three 1-1-2'
                  }
                ]
              }
            ]
          },
          {
            id: 2,
            label: 'Level one 2',
            children: [
              {
                id: 5,
                label: 'Level two 2-1'
              },
              {
                id: 6,
                label: 'Level two 2-2'
              }
            ]
          },
          {
            id: 3,
            label: 'Level one 3',
            children: [
              {
                id: 7,
                label: 'Level two 3-1'
              },
              {
                id: 8,
                label: 'Level two 3-2'
              }
            ]
          }
        ]
      }
    }
  }
</script>

其中:

  • :data:树选择器的数据源,是一个数组,表示树的节点和层级关系。
  • show-checkbox:是否显示选择框。
  • node-key:树节点的唯一标识符,默认是id属性,也可以自定义。

三、树选择器实现多级联动菜单的方法

1、数据结构准备

首先准备好需要展示的菜单数据,可以是一个数组,每个元素表示一个菜单。对于多级联动菜单,我们可以使用嵌套的形式表示,如下所示:

[
  {
    "id": "1",
    "name": "菜单1",
    "submenus": [
      {
        "id": "11",
        "name": "子菜单1",
        "submenus": [
          {
            "id": "111",
            "name": "子子菜单1"
          },
          {
            "id": "112",
            "name": "子子菜单2"
          }
        ]
      },
      {
        "id": "12",
        "name": "子菜单2"
      }
    ]
  },
  {
    "id": "2",
    "name": "菜单2",
    "submenus": [
      {
        "id": "21",
        "name": "子菜单1"
      },
      {
        "id": "22",
        "name": "子菜单2"
      }
    ]
  }
]

每个菜单对象包含以下属性:

  • id:菜单ID,用于唯一标识每个菜单。
  • name:菜单名称,用于显示在界面上。
  • submenus:子菜单,用于表示多级菜单的关系。

2、数据处理

一般情况下,树选择器的数据源格式与展示的菜单数据格式不一致,需要对数据进行处理。我们需要将菜单数据格式转换为树选择器数据源格式。

// 将菜单数据格式转换为树选择器的数据格式
function transformData(data, parentId) {
  return data.map(item => {
    const id = item.id
    const label = item.name
    const children = item.submenus || []
    const node = {
      id: id,
      label: label
    }
    if (children.length > 0) {
      node.children = transformData(children, id)
    }
    if (parentId) {
      node.parentId = parentId
    }
    return node
  })
}

// 进行数据转换
const treeData = transformData(menuData)

transformData函数将菜单数据格式转换为树选择器格式,参数data为菜单数据,parentId为父级菜单ID,用于关联父子级菜单关系。

3、实现多级联动菜单效果

多级联动菜单的效果是根据前一级菜单的选择,动态更新下一级菜单的内容。我们使用el-treenode-click事件来监听用户的选择操作,对每个菜单节点设置额外的属性level表示当前菜单的级别。

<template>
  <div class="demo-container">
    <el-col :span="8" v-for="(data, index) in menuData" :key="index">
      <el-row class="menu-row">
        <el-collapse v-model="activeIndex" accordion>
          <el-collapse-item :title="data.name" :name="'menu' + index">
            <el-tree
              class="menu-tree"
              :data="dataTree[index]"
              :props="{ label: 'name', children: 'submenus' }"
              node-key="id"
              :highlight-current="true"
              @node-click="handleNodeClick">
            </el-tree>
          </el-collapse-item>
        </el-collapse>
      </el-row>
    </el-col>
  </div>
</template>

<script>
  export default {
    data() {
      const menuData = [
        {
          id: '1',
          name: '菜单1',
          submenus: [
            {
              id: '11',
              name: '子菜单1',
              submenus: [
                {
                  id: '111',
                  name: '子子菜单1'
                },
                {
                  id: '112',
                  name: '子子菜单2'
                }
              ]
            },
            {
              id: '12',
              name: '子菜单2',
              submenus: [
                {
                  id: '121',
                  name: '子子菜单1'
                },
                {
                  id: '122',
                  name: '子子菜单2'
                }
              ]
            }
          ]
        },
        {
          id: '2',
          name: '菜单2',
          submenus: [
            {
              id: '21',
              name: '子菜单1',
              submenus: [
                {
                  id: '211',
                  name: '子子菜单1'
                },
                {
                  id: '212',
                  name: '子子菜单2'
                }
              ]
            },
            {
              id: '22',
              name: '子菜单2',
              submenus: [
                {
                  id: '221',
                  name: '子子菜单1'
                },
                {
                  id: '222',
                  name: '子子菜单2'
                }
              ]
            }
          ]
        }
      ]

      // 将菜单数据转换为树选择器的数据格式
      const dataTree = menuData.map(menu => transformData([menu])[0])

      return {
        menuData: menuData,
        dataTree: dataTree,
        activeIndex: ['menu0']
      }
    },
    methods: {
      handleNodeClick(node) {
        // 设置level属性,表示当前菜单的级别
        node.level = node.parent.level + 1 || 1

        // 获取当前菜单所在的列
        const menuIndex = +node.el.parentElement.parentElement.dataset.index

        // 关闭当前菜单所在列右侧的所有列
        for (let i = menuIndex + 1; i < this.menuData.length; i++) {
          this.activeIndex.splice(this.activeIndex.indexOf('menu' + i), 1)
        }

        // 添加当前菜单的子菜单到下一列
        const submenus = node.data.submenus || []
        if (submenus.length > 0) {
          const nextMenuIndex = menuIndex + 1
          const nextDataTree = transformData([node.data])[0].children
          if (nextDataTree.length > 0) {
            this.dataTree.splice(nextMenuIndex, 1, nextDataTree)
            this.activeIndex.push('menu' + nextMenuIndex)
          }
        }
      }
    }
  }
</script>

<style scoped>
  .demo-container {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 50vh;
  }
  .el-collapse-item {
    background-color: #f5f5f5;
  }
  .menu-row {
    min-height: 400px;
  }
  .menu-tree {
    max-height: 350px;
    overflow-y: auto;
  }
</style>

四、示例说明

1、单级菜单选择器示例

<template>
  <el-form>
    <el-form-item label="请选择一个菜单">
      <el-tree
        :data="treeData"
        :props="{ label: 'name' }"
        node-key="id"
        :highlight-current="true"
        @node-click="handleNodeClick">
      </el-tree>
    </el-form-item>
  </el-form>
</template>

<script>
  export default {
    data() {
      const menuData = [
        {
          id: '1',
          name: '菜单1'
        },
        {
          id: '2',
          name: '菜单2'
        },
        {
          id: '3',
          name: '菜单3'
        }
      ]

      // 将菜单数据转换为树选择器的数据格式
      const treeData = transformData(menuData)

      return {
        treeData: treeData
      }
    },
    methods: {
      handleNodeClick(node) {
        console.log(`您选择了菜单:${node.label}`)
      }
    }
  }
</script>

2、多级联动菜单示例

<template>
  <div class="demo-container">
    <el-col :span="8" v-for="(data, index) in menuData" :key="index" :data-index="index">
      <el-row class="menu-row">
        <el-collapse v-model="activeIndex" accordion>
          <el-collapse-item :title="data.name" :name="'menu' + index">
            <el-tree
              class="menu-tree"
              :data="dataTree[index]"
              :props="{ label: 'name', children: 'submenus' }"
              node-key="id"
              :highlight-current="true"
              @node-click="handleNodeClick">
            </el-tree>
          </el-collapse-item>
        </el-collapse>
      </el-row>
    </el-col>
  </div>
</template>

<script>
  export default {
    data() {
      const menuData = [
        {
          id: '1',
          name: '一级菜单1',
          submenus: [
            {
              id: '11',
              name: '二级菜单1.1',
              submenus: [
                {
                  id: '111',
                  name: '三级菜单1.1.1'
                },
                {
                  id: '112',
                  name: '三级菜单1.1.2'
                }
              ]
            },
            {
              id: '12',
              name: '二级菜单1.2',
              submenus: [
                {
                  id: '121',
                  name: '三级菜单1.2.1'
                },
                {
                  id: '122',
                  name: '三级菜单1.2.2',
                  submenus: [
                    {
                      id: '1221',
                      name: '四级菜单1.2.2.1'
                    },
                    {
                      id: '1222',
                      name: '四级菜单1.2.2.2'
                    }
                  ]
                }
              ]
            }
          ]
        },
        {
          id: '2',
          name: '一级菜单2',
          submenus: [
            {
              id: '21',
              name: '二级菜单2.1',
              submenus: [
                {
                  id: '211',
                  name: '三级菜单2.1.1'
                },
                {
                  id: '212',
                  name: '三级菜单2.1.2'
                }
              ]
            },
            {
              id: '22',
              name: '二级菜单2.2',
              submenus: [
                {
                  id: '221',
                  name: '三级菜单2.2.1'
                },
                {
                  id: '222',
                  name: '三级菜单2.2.2'
                }
              ]
            }
          ]
        }
      ]

      // 将菜单数据转换为树选择器的数据格式
      const dataTree = menuData.map(menu => transformData([menu])[0])

      return {
        menuData: menuData,
        dataTree: dataTree,
        activeIndex: ['menu0']
      }
    },
    methods: {
      handleNodeClick(node) {
        // 设置level属性,表示当前菜单的级别
        node.level = node.parent.level + 1 || 1

        // 获取当前菜单所在的列
        const menuIndex = +node.el.parentElement.parentElement.dataset.index

        // 关闭当前菜单所在列右侧的所有列
        for (let i = menuIndex + 1; i < this.menuData.length; i++) {
          this.activeIndex.splice(this.activeIndex.indexOf('menu' + i), 1)
        }

        // 添加当前菜单的子菜单到下一列
        const submenus = node.data.submenus || []
        if (submenus.length > 0) {
          const nextMenuIndex = menuIndex + 1
          const nextDataTree = transformData([node.data])[0].children
          if (nextDataTree.length > 0) {
            this.dataTree.splice(nextMenuIndex, 1, nextDataTree)
            this.activeIndex.push('menu' + nextMenuIndex)
          }
        }
      }
    }
  }
</script>

<style scoped>
  .demo-container {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 50vh;
  }
  .el-collapse-item {
    background-color: #f5f5f5;
  }
  .menu-row {
    min-height: 400px;
  }
  .menu-tree {
    max-height: 350px;
    overflow-y: auto;
  }
</style>

以上就是巧用树选择器实现多级联动菜单的全部内容,希望能对您有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Element UI框架中巧用树选择器的实现 - Python技术站

(0)
上一篇 2023年5月27日
下一篇 2023年5月27日

相关文章

  • Springboot+Vue-Cropper实现头像剪切上传效果

    下面是“Springboot+Vue-Cropper实现头像剪切上传效果”的完整攻略。 前置知识 在学习本文之前,需要了解以下内容: Spring Boot框架 Vue.js框架 Vue-Cropper组件 环境准备 JDK 1.8 Maven Node.js Vue CLI 前端实现 创建Vue项目 在命令行中执行以下命令: vue create vue-…

    Vue 2023年5月28日
    00
  • 在vscode里使用.vue代码模板的方法

    当你在VS Code中编写Vue应用程序时,使用Vue代码模板可以提高你的代码编写效率。以下是在VS Code中使用Vue代码模板的完整攻略以及两个示例说明。 步骤一:安装Vetur插件 首先,在VS Code中安装Vetur插件,该插件能够帮助你为Vue应用程序启用代码高亮和自动完成。你可以按下快捷键“Ctrl + Shift + X”打开VS Code的…

    Vue 2023年5月28日
    00
  • Vue数据劫持详情介绍

    一、Vue数据劫持介绍 在Vue中,数据劫持是Vue实现双向数据绑定的核心机制。Vue通过数据劫持,可以在数据被设置时拦截操作,从而更新对应的视图,同时在视图更新时,也能更新数据。Vue基于ES5的Object.defineProperty()方法实现数据劫持。 二、数据劫持的流程 首先,在Vue初始化时,会对data选项中的每一个属性调用Object.de…

    Vue 2023年5月29日
    00
  • Vue实现多标签选择器

    确定需求 首先,我们需要明确自己的需求,即实现一个多标签选择器,让用户能够方便地选择多个标签进行操作。在确定需求的时候,我们需要考虑如下问题: 该多标签选择器需要支持哪些操作,比如添加标签、删除标签、清空标签等等。 该多标签选择器是否需要支持搜索,用户可以搜索标签进行选择。 多标签选择器的样式应该如何设计,方便用户使用。 在确认好需求之后,我们就可以着手开始…

    Vue 2023年5月27日
    00
  • Vue中$on和$emit的实现原理分析

    Vue中$on和$emit的实现原理分析 介绍 在Vue中,$on和$emit是两个非常常用的方法,用于实现事件的监听和触发。$on方法用于监听事件,$emit方法用于触发事件。本文将对Vue中$on和$emit的实现原理进行分析和讲解。 $on的实现原理 $on方法用于监听事件,其实现原理很简单,就是将事件名和事件处理函数保存到一个对象中。在触发事件时,遍…

    Vue 2023年5月28日
    00
  • vue获取时间戳转换为日期格式代码实例

    本次我们将详细讲解一下“vue获取时间戳转换为日期格式代码实例”。 一、什么是时间戳 时间戳(Timestamp)是指格林威治时间1970年01月01日00时00分00秒起至现在的总秒数。时间戳常用于计算时间间隔和标记时间等情况。 二、获取时间戳 在 Vue 中,可以使用 JavaScript 自带的 Date.now() 方法获取当前时间戳。代码如下: l…

    Vue 2023年5月27日
    00
  • Vue程序化的事件监听器(实例方案详解)

    关于“Vue程序化的事件监听器(实例方案详解)”的完整攻略,我这里给出以下内容: 什么是程序化的事件监听器 程序化的事件监听器,顾名思义就是通过编写程序来实现对一些特定事件的监听。在Vue中,可以通过编写一些代码来监听某些事件的发生,这些事件可以是页面的滚动、鼠标的点击或移动等等。 如何在Vue中实现程序化的事件监听器 在Vue中实现程序化的事件监听器通常有…

    Vue 2023年5月27日
    00
  • 实例分析vue循环列表动态数据的处理方法

    下面我就给你详细讲解“实例分析Vue循环列表动态数据的处理方法”的完整攻略。 一、问题描述 当我们需要循环列表显示数据时,如果数据是动态的,我们该怎么处理呢?比如,我们要在页面中展示一些文章列表,这些文章在不停地更新,我们需要实现哪些功能呢? 实时获取最新列表数据并展示出来 定时更新列表数据,以保证数据的及时性 点击某篇文章,能够跳转到对应的文章详情页面 二…

    Vue 2023年5月29日
    00
合作推广
合作推广
分享本页
返回顶部