一、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-tree
的node-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技术站