随着互联网的发展,越来越多的网站需要实现多级导航菜单来展示各种分类和子分类,以方便用户的浏览和使用。在前端框架中,Vue 也提供了很好的支持来帮助我们实现多级导航菜单。本文将介绍如何使用 Vue 实现多级导航菜单。
一、基本概念
在使用 Vue 实现多级导航菜单之前,我们需要了解一些基本概念:
- 节点 (node):树状结构中的每一个元素都被称为一个节点。
- 根节点 (root node):树状结构中最顶层的节点被称为根节点。
- 叶子节点 (leaf node):树状结构中没有子节点的节点被称为叶子节点。
- 父节点 (parent node):具有子节点的节点被称为父节点。
- 子节点 (child node):被父节点所包含并作为其直接后代出现的节点被称为子节点。
二、数据结构设计
在 Vue 中实现多级导航菜单,我们需要定义一个数据结构来存储菜单的数据。我们可以使用 JSON 格式来存储菜单数据。我们需要为每个菜单项定义以下属性:
- id:每个菜单项都需要有一个唯一的 id。
- title:菜单的标题。
- icon:菜单的图标。
- path:菜单的链接。
- children:下一级菜单的数据,如果当前菜单是叶子节点,则 children 为空数组。
下面是一个简单的多级菜单数据示例:
[ { "id": 1, "title": "菜单 1", "icon": "fa fa-home", "path": "/menu1", "children": [ { "id": 11, "title": "菜单 1-1", "icon": "fa fa-book", "path": "/menu1-1", "children": [ { "id": 111, "title": "菜单 1-1-1", "icon": "fa fa-link", "path": "/menu1-1-1", "children": [] }, { "id": 112, "title": "菜单 1-1-2", "icon": "fa fa-link", "path": "/menu1-1-2", "children": [] } ] }, { "id": 12, "title": "菜单 1-2", "icon": "fa fa-book", "path": "/menu1-2", "children": [] } ] }, { "id": 2, "title": "菜单 2", "icon": "fa fa-home", "path": "/menu2", "children": [ { "id": 21, "title": "菜单 2-1", "icon": "fa fa-book", "path": "/menu2-1", "children": [] }, { "id": 22, "title": "菜单 2-2", "icon": "fa fa-book", "path": "/menu2-2", "children": [] } ] } ]
三、组件设计
在 Vue 中实现多级导航菜单,我们可以使用组件来构建。由于多级导航菜单是一棵树状结构,我们可以使用递归组件来创建树形结构的菜单。递归组件是指组件在它的模板中调用自己。
- Menu 组件
Menu 组件是我们的根组件,它调用 MenuItem 组件来创建菜单项,并根据不同的层级来设置样式。
<template> <ul class="menu"> <menu-item v-for="(item, index) in list" :key="item.id" :item="item" :level="1" :last="index === list.length - 1" ></menu-item> </ul> </template> <script> import MenuItem from './MenuItem.vue'; export default { name: 'Menu', components: { MenuItem, }, props: { list: { type: Array, required: true, }, }, }; </script> <style scoped> .menu { padding: 0; margin: 0; } </style>
- MenuItem 组件
MenuItem 组件根据传入的菜单数据来创建菜单项,并判断当前的菜单项是否有下一级菜单项,如果有则递归创建下一级菜单,否则显示当前菜单项的链接地址。
<template> <li :class="{'has-children': hasChildren}"> <router-link :to="item.path"><i :class="item.icon"></i>{{ item.title }}</router-link> <ul v-if="hasChildren"> <menu-item v-for="(child, index) in item.children" :key="child.id" :item="child" :level="level + 1" :last="index === item.children.length - 1" ></menu-item> </ul> </li> </template> <script> import MenuItem from './MenuItem.vue'; export default { name: 'MenuItem', components: { MenuItem, }, props: { item: { type: Object, required: true, }, level: { type: Number, required: true, }, last: { type: Boolean, default: false, }, }, computed: { hasChildren() { return this.item.children && this.item.children.length > 0; }, indent() { return { paddingLeft: `${this.level * 20}px`, borderBottom: this.last ? 'none' : '', }; }, }, }; </script> <style scoped> .has-children { position: relative; } li i { margin-right: 5px; } ul { margin: 0; padding: 0; } li { list-style: none; } li:last-child { border-bottom: none; } </style>
四、使用案例
接下来我们将在一个 Vue 项目中使用我们所创建的多级导航菜单组件。
- 创建 Vue 项目
我们可以使用 Vue CLI 来创建一个 Vue 项目:
npm install -g @vue/cli vue create my-project
- 安装 Vue 路由
我们需要使用 Vue 路由来管理页面的跳转:
npm install vue-router --save
- 配置 Vue 路由
我们需要在 Vue 项目中配置路由,将不同的路由跳转到不同的页面。将路由的 path 设置为在菜单数据中定义的 path,当用户点击菜单项时,就会从 / 跳转到对应的页面。
import Vue from 'vue'; import VueRouter from 'vue-router'; import Home from './views/Home.vue'; import About from './views/About.vue'; Vue.use(VueRouter); const routes = [ { path: '/', redirect: '/home', }, { path: '/home', name: 'Home', component: Home, }, { path: '/about', name: 'About', component: About, }, ]; const router = new VueRouter({ mode: 'history', base: process.env.BASE_URL, routes, }); export default router;
- 渲染多级导航菜单
我们可以在页面中使用 Menu 组件来渲染多级导航菜单。
<template> <div id="app"> <menu :list="menu"></menu> <router-view></router-view> </div> </template> <script> import Menu from './components/Menu.vue'; export default { name: 'App', components: { Menu, }, data() { return { menu: [ { id: 1, title: '首页', icon: 'fa fa-home', path: '/home', children: [], }, { id: 2, title: '关于我们', icon: 'fa fa-info', path: '/about', children: [], }, { id: 3, title: '产品分类', icon: 'fa fa-product-hunt', path: '', children: [ { id: 31, title: '手机', icon: 'fa fa-mobile', path: '/products/mobile', children: [ { id: 311, title: '苹果', icon: 'fa fa-apple', path: '/products/mobile/apple', children: [ { id: 3111, title: 'iPhone 12', icon: 'fa fa-gift', path: '/products/mobile/apple/iphone-12', children: [], }, { id: 3112, title: 'iPhone 11', icon: 'fa fa-gift', path: '/products/mobile/apple/iphone-11', children: [], }, ], }, { id: 312, title: '华为', icon: 'fa fa-huawei', path: '/products/mobile/huawei', children: [ { id: 3121, title: 'Mate 40 Pro', icon: 'fa fa-gift', path: '/products/mobile/huawei/mate-40-pro', children: [], }, { id: 3122, title: 'P40', icon: 'fa fa-gift', path: '/products/mobile/huawei/p40', children: [], }, ], }, ], }, { id: 32, title: '电脑', icon: 'fa fa-desktop', path: '/products/computer', children: [ { id: 321, title: '联想', icon: 'fa fa-link', path: '/products/computer/lenovo', children: [ { id: 3211, title: 'ThinkPad X1', icon: 'fa fa-gift', path: '/products/computer/lenovo/thinkpad-x1', children: [], }, { id: 3212, title: 'IdeaPad 5', icon: 'fa fa-gift', path: '/products/computer/lenovo/ideapad-5', children: [], }, ], }, { id: 322, title: '戴尔', icon: 'fa fa-dell', path: '/products/computer/dell', children: [ { id: 3221, title: 'XPS 13', icon: 'fa fa-gift', path: '/products/computer/dell/xps-13', children: [], }, { id: 3222, title: 'Inspiron 14 7000', icon: 'fa fa-gift', path: '/products/computer/dell/inspiron-14-7000', children: [], }, ], }, ], }, ], }, ], }; }, }; </script>
五、总结
Vue 提供了很好的支持来帮助我们实现多级导航菜单。使用递归组件来创建树形结构的菜单,可以使代码更简洁易懂。在设计菜单数据时,需要注意属性的命名和菜单的层级关系,这有助于我们在递归组件中更好地实现多级导航菜单。