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

yizhihongxing

一、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脚手架创建项目时报catch错误及解决

    当使用Vue CLI创建项目时,如果遇到以下错误: Error: EACCES: permission denied, open ‘/Users/username/.config/configstore/insight-nodejs/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX’ You don’t have access to this f…

    Vue 2023年5月28日
    00
  • vue3中调用api接口实现数据的渲染以及详情方式

    当我们在Vue 3中进行开发时,我们通常需要与后端API进行数据交互。这里提供一个完整的攻略,帮助开发者学习如何在Vue 3中调用API接口实现数据的渲染以及详情方式。 步骤一:安装和引入axios Axios是一个流行的网络请求库,我们可以通过npm命令来安装: npm install axios 在Vue 3中,我们通常通过在main.js中全局引入ax…

    Vue 2023年5月28日
    00
  • vue实现把接口单独存放在一个文件方式

    在Vue项目中,我们可以将接口单独存放在一个文件中,以便于统一管理和维护,提高开发效率。以下是详细攻略: 1. 创建接口配置文件 在项目中创建一个api目录,用于存放所有接口配置文件。在api目录下新建一个文件,如 index.js。示例代码: import axios from ‘axios’ const service = axios.create({ …

    Vue 2023年5月28日
    00
  • 教你如何优化 Vue.js 应用程序

    教你如何优化 Vue.js 应用程序 Vue.js是一款流行的现代化JavaScript框架,用于开发用户界面。Vue.js能够以高效且灵活的方式管理数据与交互,不过在大型应用中,可能会出现性能问题。本文将提供一些优化Vue.js应用程序的技巧。 1. 使用Vue.js的异步组件 对于大型Vue.js应用程序,为了使单个Vue文件大小更小,可以使用异步组件。…

    Vue 2023年5月27日
    00
  • webpack4+Vue搭建自己的Vue-cli项目过程分享

    下面我就来详细讲解“webpack4+Vue搭建自己的Vue-cli项目过程分享”的完整攻略。 1. 创建Vue项目 使用Vue-cli可快速搭建Vue项目结构。首先,我们需要全局安装Vue-cli: npm install -g vue-cli 然后,运行以下命令来创建Vue项目: vue init webpack my-project cd my-pro…

    Vue 2023年5月27日
    00
  • 一篇超详细的Vue-Router手把手教程

    一篇超详细的Vue-Router手把手教程 简介 Vue-Router是Vue.js官方提供的用于路由管理的插件,可以帮助我们快速地构建单页应用。本文将从基础的使用开始,逐步深入解析Vue-Router的特性和使用方法,让你轻松掌握Vue-Router的使用。 基本使用 安装 使用npm安装Vue-Router: npm install vue-router…

    Vue 2023年5月27日
    00
  • vue 父组件通过v-model接收子组件的值的代码

    当一个子组件改变了它的状态时,父组件也会相应地随着子组件改变。Vue提供了 v-model 指令来实现这种双向绑定的效果。在子组件中,要使用 this.$emit(‘input’, value) 将数据通过 input 事件的方式发送到父组件中,然后父组件通过 v-model 指令绑定这个事件和值即可。 举例来说,我们现在有一个父组件 Parent.vue …

    Vue 2023年5月27日
    00
  • Vue3插槽Slot实现原理详解

    下面我将为你详细讲解“Vue3插槽Slot实现原理详解”的完整攻略。 什么是插槽(Slot) 在Vue开发中,有时候我们需要在父组件中定义子组件的模板结构,但是子组件的内容是不确定的。这种情况下,我们可以使用插槽(Slot)来解决问题。 插槽允许我们定义一个承载子组件内容的挂载点,然后在子组件中使用具名插槽(Named Slot)或默认插槽(Default …

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