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日

相关文章

  • vue使用websocket概念及示例

    要理解Vue.js如何使用Websocket,我们需要先了解什么是Websocket。Websocket是一种实现全双工通信的协议,它允许浏览器和服务器之间实时通信,而不需要完全依靠HTTP请求响应模式。 接下来,我们将为您介绍如何在Vue.js应用程序中使用Websocket。 步骤1:安装和导入WebSocket应用程序 首先,我们需要安装Websock…

    Vue 2023年5月27日
    00
  • Vue Ref全家桶具体用法详解

    Vue Ref全家桶具体用法详解 在 Vue 中,我们经常需要访问到组件中的元素,例如获取 input 标签的值、获取 canvas 画布、操作 DOM 等,这时候 Ref 就是一个很友好的工具。Vue 3.0 进一步细化了 Ref 的分类,分别是 Ref、Reactive Ref、Shallow Ref、To Ref 四种类型,可以更加精细地控制数据是否为…

    Vue 2023年5月28日
    00
  • Vue实现在线预览pdf文件功能(利用pdf.js/iframe/embed)

    下面我将为你详细讲解如何用Vue实现在线预览pdf文件功能,对应的技术包括pdf.js、iframe、embed等。 1. 准备工作 首先,需要下载pdf.js(官网地址)并引入到Vue项目中。在main.js中引入如下: import pdfjsLib from ‘pdfjs-dist/build/pdf’; import pdfWorker from ‘…

    Vue 2023年5月28日
    00
  • 详解如何在vue-cli中使用vuex

    下面为您详细讲解如何在vue-cli中使用vuex。 什么是Vuex? Vuex是一个专为Vue.js应用程序开发的状态管理模式和库。它采用集中式存储管理应用的所有组件的状态,并以可预测的方式发起状态的改变。它的核心概念包括Store、State、Getter、Mutation、Action和Module。 如何在vue-cli中使用vuex? 以下是一些简…

    Vue 2023年5月27日
    00
  • vue.js将时间戳转化为日期格式的实现代码

    关于Vue.js将时间戳转化为日期格式的实现代码,以下是完整的攻略: 前置知识 在进行该任务之前,我们需要了解一些基础知识: 时间戳是指从1970年1月1日以来经过的秒数,可以通过new Date().getTime()来获取当前的时间戳; 要将时间戳转化为日期格式,需要用到JavaScript内置的Date对象,并搭配format库进行格式化,使用方法可以…

    Vue 2023年5月29日
    00
  • vue2.0移动端滑动事件vue-touch的实例代码

    下面我将详细讲解vue2.0移动端滑动事件vue-touch的实例代码的完整攻略。 简介 Vue-Touch是一个基于HammerJS封装的适用于Vue2.x的触摸插件。它可以在Vue组件中使用v-touch指令,实现触屏事件的绑定和处理,包括Tap、Doubletap、Press、Swipe、Pinch、Rotate等常见的手势事件。 安装 在使用vue-…

    Vue 2023年5月29日
    00
  • 解析Vue2 dist 目录下各个文件的区别

    Vue2 是一款流行的 JavaScript 前端框架,它的 dist 目录下包含了多个文件,每个文件都有自己的职责和用途。下面我将详细讲解 Vue2 dist 目录下各个文件的区别。 vue.js vue.js 文件是最基本的 Vue2 库文件,包含了 Vue 的核心代码和各种插件。如果你只想使用 Vue 就可以将这个文件添加到你的 HTML 文件中,然后…

    Vue 2023年5月28日
    00
  • Vue3.2.x中的小技巧及注意事项总结

    Vue3.2.x中的小技巧及注意事项总结 Vue 3.2.x是一款非常便于使用的前端框架,但是在使用的过程中还是需要注意一些小技巧和细节,本文将对这些内容进行总结。 注意事项 1. Composition API VS Options API Vue 3.2.x引入了Composition API,这是一种新的API风格,它使用function-based …

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