element 导航栏(【前端】Vue+Element UI案例:通用后台管理系统-导航栏)
参考视频:
VUE项目 ,VUE项目实战 ,vue后台管理系统 ,前端面试 ,前端面试项目 案例 链接 【前端】Vue+Element UI案例:通用后台管理系统-导航栏(视频p1-16) https://blog.csdn.net/karshey/article/details/127640658 【前端】Vue+Element UI案例:通用后台管理系统-Header+导航栏折叠(p17-19) https://blog.csdn.net/karshey/article/details/127652862 【前端】Vue+Element UI案例:通用后台管理系统-Home组件:卡片 、表格(p20-22) https://blog.csdn.net/karshey/article/details/127674643 【前端】Vue+Element UI案例:通用后台管理系统-Echarts图表准备:axios封装 、mock数据模拟实战(p23-25) https://blog.csdn.net/karshey/article/details/127735159 【前端】Vue+Element UI案例:通用后台管理系统-Echarts图表:折线图、柱状图 、饼状图(p27-30) https://blog.csdn.net/karshey/article/details/127737979 【前端】Vue+Element UI案例:通用后台管理系统-面包屑 、tag栏(p31-35) https://blog.csdn.net/karshey/article/details/127756733 【前端】Vue+Element UI案例:通用后台管理系统-用户管理:Form表单填写 、Dialog对话框弹出(p36-38) https://blog.csdn.net/karshey/article/details/127787418 【前端】Vue+Element UI案例:通用后台管理系统-用户管理:Table表格增删查改 、Pagination分页 、搜索框(p39-42) https://blog.csdn.net/karshey/article/details/127777962 【前端】Vue+Element UI案例:通用后台管理系统-登陆页面Login(p44) https://blog.csdn.net/karshey/article/details/127795302 【前端】Vue+Element UI案例:通用后台管理系统-登陆页面功能:登录权限跳转 、路由守卫 、退出(p45-46) https://blog.csdn.net/karshey/article/details/127849502 【前端】Vue+Element UI案例:通用后台管理系统-登陆不同用户显示不同菜单 、动态添加路由(p47-48) https://blog.csdn.net/karshey/article/details/127865621 【前端】Vue+Element UI案例:通用后台管理系统-项目总结 https://blog.csdn.net/karshey/article/details/127867638目标
悬停效果 点击效果 其他:点击展开和收缩 动态显示“首页 ”“商品管理 ”等 有路由跳转其实是项目的导航栏组件 。只打算看导航栏部分的可以跳过1.其他准备 。
代码
0.数据
我们把它单独放到一个MenuData.js中 ,然后用export default暴露出来 。
{ path: /, name: home, label: 首页, icon: s-home, url: Home/Home }, { path: /mall, name: mall, label: 商品管理, icon: video-play, url: MallManage/MallManage }, { path: /user, name: user, label: 用户管理, icon: user, url: UserManage/UserManage }, { label: 其他, icon: location, children: [ { path: /page1, name: page1, label: 页面1, icon: setting, url: Other/PageOne }, { path: /page2, name: page2, label: 页面2, icon: setting, url: Other/PageTwo } ] }1.其他准备
注意要查看官方文档:官方文档
全局引入Element UI
先安装Element UI:
npm i element-ui -S全局引入:在main.js中
import ElementUI from element-ui Vue.use(ElementUI)路由配置
这里我们先配置Home页面(会显示导航栏的页面) 。官方文档:Vue Router
安装:这里的版本是3.6.5
ps:可以在npm网站上查到包的所有版本 ,我们这里要的是3.x.x的最新版 。 npm install vue-router@3.6.5路由的配置:目前只配置了Main组件的
import Vue from "vue"; import VueRouter from "vue-router"; import Main from ../Views/Main Vue.use(VueRouter) const routes=[ // 主路由 { path:/, component:Main } ] const router = new VueRouter({ routes }) export default router目前的依赖 当前的package.json文件的dependencies应当如下:
"dependencies": { "core-js": "^3.8.3", "element-ui": "^2.15.10", "vue": "^2.6.14", "vue-router": "^3.6.5" }当前的main.js
import Vue from vue import App from ./App.vue import ElementUI from element-ui import element-ui/lib/theme-chalk/index.css; import router from ./router/index Vue.config.productionTip = false Vue.use(ElementUI) new Vue({ router, render: h => h(App), }).$mount(#app)Main.vue布局结构
要的是这个布局:
找到对应代码: <el-container> <el-aside width="200px">Aside</el-aside> <el-container> <el-header>Header</el-header> <el-main>Main</el-main> </el-container> </el-container>把它放到Main.vue里 。
App.vue如下:
<template> <div id="app"> <router-view></router-view> </div> </template> <script> export default { } </script> <style></style>效果:
接下来我们写一个组件:CommonAside.vue ,把导航栏写在这个组件里 ,再把组件放到Aside中 。因此放了布局的Main.vue如下:
<template> <el-container> <el-aside width="200px"> <common-aside/> </el-aside> <el-container> <el-header>Header</el-header> <el-main>Main</el-main> </el-container> </el-container> </template> <script> import CommonAside from ../components/CommonAside.vue export default { data(){ return{} }, components:{ CommonAside } } </script> <style></style>组件CommonAside如下:
<template> <!-- 在这里开始写导航栏 --> </template> <script> export default { } </script> <style></style>接下来就是本文正题:导航栏 。
2.结构
Element UI文档
我们现在Element UI官方文档上找到类似的导航结构:就是你了!
阅读代码 ,我们不难发现代码分为“展开收起”部分和“导航 ”部分,我们要的是导航部分 。把代码对着我们的目标稍作调整得到: <el-menu default-active="1-4-1" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose" :collapse="isCollapse"> <el-menu-item index="2"> <i class="el-icon-menu"></i> <span slot="title">导航一</span> </el-menu-item> <el-submenu index="1"> <template slot="title"> <i class="el-icon-location"></i> <span slot="title">导航二</span> </template> <el-menu-item-group> <span slot="title">分组一</span> <el-menu-item index="1-1">选项1</el-menu-item> <el-menu-item index="1-2">选项2</el-menu-item> </el-menu-item-group> </el-submenu> </el-menu>效果:
3.动态显示数据
导航栏分为一级导航栏和二级导航栏 ,目标中的 其他-页面1 就是二级导航栏 ,首页 、商品管理、用户管理 都是一级导航栏。
一级和二级的区别在于:数据中是否有children属性,如果有 ,那它的children属性就是二级导航 。所以这里要用到计算属性 。
computed:{ noChildren(){ // 如果没有children则返回true,会被过滤器留下 return this.MenuData.filter(item=>!item.children) }, hasChildren(){ return this.MenuData.filter(item=>item.children) } }一级导航栏的循环显示:
<!-- 观察数据,我们发现name是唯一标识 --> <!-- 查看文档,index是唯一标识 --> <el-menu-item v-for="item in noChildren" :key="item.name" :index="item.name"> <!-- 这里是字体图标,用模板字符串拼接,注意要动态绑定 --> <i :class="`el-icon-${item.icon}`"></i> <span slot="title">{{item.label}}</span> </el-menu-item>效果:
二级导航栏也是类似做法: <el-submenu v-for="item in hasChildren" :key="item.name" :index="item.name"> <template slot="title"> <i :class="`el-icon-${item.icon}`"></i> <span slot="title">{{item.label}}</span> </template> <el-menu-item-group v-for="subItem in item.children" :key="subItem.name"> <el-menu-item :index="subItem.name">{{subItem.label}}</el-menu-item> </el-menu-item-group> </el-submenu> </el-menu>效果:
4.主题:背景色 ,点击悬停效果
再次打开文档,找到自定义颜色部分:
显然是这里:我们把它直接复制粘贴。
则标签如下: <el-menu default-active="1-4-1" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose" :collapse="isCollapse" background-color="#545c64" text-color="#fff" active-text-color="#ffd04b">效果:就是这样!
5.去除padding
在浏览器中F12可知 ,padding是由body等标签自动带有的 ,我们只需要在App.vue中把它们清除即可(reset) 。
html, body, h3, p { margin: 0; padding: 0 }6.去除下拉框
这里我们先安装less:这样写CSS可以嵌套 ,更加方便 。
npm install less less-loader --save浏览器F12 ,显然有下拉框的这个类是:el-menu
把el-menu设置成height:100vh即可。7.标题
html:
<!-- 要放到导航栏里面 --> <h3>通用后台管理系统</h3>css:
<style lang="less" scoped> .el-menu{ height:100vh; h3{ text-align: center; line-height: 48px; color: #fff; font-size: 16px; font-weight: 400; } } </style>效果:
8.路由跳转
添加点击事件:
<el-menu-item @click="clickItem(item)" v-for="item in noChildren" :key="item.name" :index="item.name"> <el-menu-item-group v-for="subItem in item.children" :key="subItem.name"> <el-menu-item @click="clickItem(subItem)" :index="subItem.name">{{ subItem.label }}</el-menu-item> </el-menu-item-group>js:
clickItem(item){ // 防止自己跳自己的报错 if(this.$route.path!==item.path&&!(this.$route.path===/home&&(item.path===/))){ this.$router.push(item.path) } }不过目前只有一个路由 。
总代码
组件CommonAside.vue
<template> <el-menu default-active="1-4-1" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose" :collapse="isCollapse" background-color="#545c64" text-color="#fff" active-text-color="#ffd04b"> <!-- 要放到导航栏里面 --> <h3>通用后台管理系统</h3> <!-- 观察数据,我们发现name是唯一标识 --> <!-- 查看文档,index是唯一标识 --> <el-menu-item @click="clickItem(item)" v-for="item in noChildren" :key="item.name" :index="item.name"> <!-- 这里是字体图标,用模板字符串拼接,注意要动态绑定 --> <i :class="`el-icon-${item.icon}`"></i> <span slot="title">{{ item.label }}</span> </el-menu-item> <el-submenu v-for="item in hasChildren" :key="item.name" :index="item.name"> <template slot="title"> <i :class="`el-icon-${item.icon}`"></i> <span slot="title">{{ item.label }}</span> </template> <el-menu-item-group @click="clickItem(subItem)" v-for="subItem in item.children" :key="subItem.name"> <el-menu-item :index="subItem.name">{{ subItem.label }}</el-menu-item> </el-menu-item-group> </el-submenu> </el-menu> </template> <style lang="less" scoped> .el-menu-vertical-demo:not(.el-menu--collapse) { width: 200px; min-height: 400px; } .el-menu{ height:100vh; h3{ text-align: center; line-height: 48px; color: #fff; font-size: 16px; font-weight: 400; } } </style> <script> import MenuData from ../data/MenuData export default { data() { return { isCollapse: false, MenuData }; }, methods: { handleOpen(key, keyPath) { console.log(key, keyPath); }, handleClose(key, keyPath) { console.log(key, keyPath); }, clickItem(item){ // 防止自己跳自己的报错 if(this.$route.path!==item.path&&!(this.$route.path===/home&&(item.path===/))){ this.$router.push(item.path) } } }, computed: { noChildren() { // 如果没有children则返回true,会被过滤器留下 return this.MenuData.filter(item => !item.children) }, hasChildren() { return this.MenuData.filter(item => item.children) } } } </script>文件结构
参考
VUE项目 ,VUE项目实战 ,vue后台管理系统 ,前端面试 ,前端面试项目:p1-16
创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!