位置: IT常识 - 正文

Vue实战【调整Vue-element-admin中的菜单栏,并添加顶部模块菜单栏】(vue设置宽度)

编辑:rootadmin
Vue实战【调整Vue-element-admin中的菜单栏,并添加顶部模块菜单栏】 目录🌟前言🌟小伙伴们先看🌟实现思路🌟具体代码🌟最后🌟前言

推荐整理分享Vue实战【调整Vue-element-admin中的菜单栏,并添加顶部模块菜单栏】(vue设置宽度),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:vue设置rem,vue设置宽度,vue-resize,vue怎么设置dialog高度,vue3.0改变,vue怎么设置dialog高度,vue 怎么调试,vue3.0改变,内容如对您有帮助,希望把文章链接给更多的朋友!

因为最近在整合公司的项目,需要把所有系统里的功能集成到一个项目里,这样就导致菜单栏目录会特别的多,不便于用户使用,体验效果极差。于是想到了一个方法,就是增加顶部导航栏,点击的时候让侧边菜单栏在显示相对应模块的所有菜单;这样的话就可以很大程度提升我们的用户体验啦。

🌟小伙伴们先看

🌟实现思路Vue实战【调整Vue-element-admin中的菜单栏,并添加顶部模块菜单栏】(vue设置宽度)

嗯,干活前一定要先把思路理清楚,记在小本本上,画个图都行哈哈

布局方面我需要在Navbar组件内添加一个导航组件以便我们去渲染顶部模块菜单;因为是动态路由所以我们可以:登录的时候让后端返回所有的当前用户下所有的菜单权限;登录时候只返回默认显示的菜单,每次点击的时候再去获取相应的模块菜单权限。

我这边用的是第一种方式,登陆的时候获取全部的存在vuex里,每次点击的时候再去处理相应的数据;小伙伴们也可以尝试一下第二种方式哦。

🌟具体代码

话不多说,直接开整。。。

<!--src/layout/components/Navbar.vue--><template> <div class="navbar"> <hamburger :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" /> <!--重点一:顶部menu--> <el-menu mode="horizontal" default-active="/" @select="handleSelect" > <el-menu-item v-for="item in menuList" :key="item.path" class="menuItem" :index="item.path"> <icon :class="item.meta?item.meta.icon:''" /> <span slot="title">{{ item.name }}</span> </el-menu-item> </el-menu> <div class="right-menu"> <el-dropdown class="avatar-container" trigger="click"> <div class="avatar-wrapper"> <img :src="avatar+'?imageView2/1/w/80/h/80'" class="user-avatar"> <i class="el-icon-caret-bottom" /> </div> <el-dropdown-menu slot="dropdown" class="user-dropdown"> <router-link to="/"> <el-dropdown-item> Home </el-dropdown-item> </router-link> <a target="_blank" href="https://github.com/PanJiaChen/vue-admin-template/"> <el-dropdown-item>Github</el-dropdown-item> </a> <a target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/#/"> <el-dropdown-item>Docs</el-dropdown-item> </a> <el-dropdown-item divided @click.native="logout"> <span style="display:block;">Log Out</span> </el-dropdown-item> </el-dropdown-menu> </el-dropdown> </div> </div></template><script>import { mapGetters } from 'vuex'import Breadcrumb from '@/components/Breadcrumb'import Hamburger from '@/components/Hamburger'export default { components: { Breadcrumb, Hamburger }, computed: { ...mapGetters([ 'sidebar', 'avatar' ]), toIndex() { // 根据路径绑定到对应的一级菜单,防止页面刷新重新跳回第一个 return '/' + this.$route.path.split('/')[1] } }, // eslint-disable-next-line vue/order-in-components data() { return { menuList: [ // 水平一级菜单栏的菜单 ] } }, mounted() { // 初始化菜单数据 this.initMenuList() }, methods: { // 重点二: // 因为整个项目工程比较大,所以当时搭建了一个demo,菜单数据我写在了本地; // 大家在实现的时候可以通过上边第一种方法; // 后台获取回来数据以后通过 router.addRoutes(获取回来的菜单数组)方法; // 动态的挂载到我们的router上。 initMenuList() { const menuList = ['/login', '/404'] this.menuList = this.$router.options.routes.filter((v, i) => { return v.path !== menuList[i] }) }, // 重点三: // 根据当前惦记的顶部模块菜单去切换左侧菜单栏,把当前点击的菜单path存在vuex里 // 我这边是存在了store/modules/user里边,这个没有要求,小伙伴们随意 handleSelect(path) { this.$store.dispatch('user/setPath', path) }, toggleSideBar() { this.$store.dispatch('app/toggleSideBar') }, async logout() { await this.$store.dispatch('user/logout') this.$router.push(`/login?redirect=${this.$route.fullPath}`) } }}</script><style lang="scss" scoped>.navbar { display: flex; justify-content: space-between; height: 50px; overflow: hidden; position: relative; background: #fff; box-shadow: 0 1px 4px rgba(0,21,41,.08); .hamburger-container { line-height: 46px; height: 100%; float: left; cursor: pointer; transition: background .3s; -webkit-tap-highlight-color:transparent; &:hover { background: rgba(0, 0, 0, .025) } } .breadcrumb-container { float: left; } .right-menu { float: right; height: 100%; line-height: 50px; &:focus { outline: none; } .right-menu-item { display: inline-block; padding: 0 8px; height: 100%; font-size: 18px; color: #5a5e66; vertical-align: text-bottom; &.hover-effect { cursor: pointer; transition: background .3s; &:hover { background: rgba(0, 0, 0, .025) } } } .avatar-container { margin-right: 30px; .avatar-wrapper { margin-top: 5px; position: relative; .user-avatar { cursor: pointer; width: 40px; height: 40px; border-radius: 10px; } .el-icon-caret-bottom { cursor: pointer; position: absolute; right: -20px; top: 25px; font-size: 12px; } } } }} .menuItem{ height: 47px; }</style>// src/store/modules/userimport { login, logout, getInfo } from '@/api/user'import { getToken, setToken, removeToken } from '@/utils/auth'import { resetRouter } from '@/router'const getDefaultState = () => { return { token: getToken(), name: '', avatar: '', // 定义以下两个状态 menuList: [], // 动态路由 path: '/' // 当前点击的菜单模块path }}const state = getDefaultState()const mutations = { RESET_STATE: (state) => { Object.assign(state, getDefaultState()) }, SET_TOKEN: (state, token) => { state.token = token }, SET_NAME: (state, name) => { state.name = name }, SET_AVATAR: (state, avatar) => { state.avatar = avatar }, // 定义SET_MENULIST方法用来保存我们的动态路由 SET_MENULIST: (state, menuList) => { state.menuList = menuList }, // 定义SET_MENULIST方法用来保存我当前点击的顶部模块菜单path SET_PATH: (state, path) => { state.path = path }}const actions = { // user login login({ commit }, userInfo) { const { username, password } = userInfo return new Promise((resolve, reject) => { login({ username: username.trim(), password: password }).then(response => { const { data } = response commit('SET_TOKEN', data.token) setToken(data.token) resolve() }).catch(error => { reject(error) }) }) }, //定义两个actions 方法用来执行我们上边定义的SET_MENULIST和SET_PATH setMenuList({ commit }, menuList) { commit('SET_MENULIST', menuList) }, setPath({ commit }, path) { commit('SET_PATH', path) }, // get user info getInfo({ commit, state }) { return new Promise((resolve, reject) => { getInfo(state.token).then(response => { const { data } = response if (!data) { return reject('Verification failed, please Login again.') } const { name, avatar } = data commit('SET_NAME', name) commit('SET_AVATAR', avatar) resolve(data) }).catch(error => { reject(error) }) }) }, // user logout logout({ commit, state }) { return new Promise((resolve, reject) => { logout(state.token).then(() => { removeToken() // must remove token first resetRouter() commit('RESET_STATE') resolve() }).catch(error => { reject(error) }) }) }, // remove token resetToken({ commit }) { return new Promise(resolve => { removeToken() // must remove token first commit('RESET_STATE') resolve() }) }}export default { namespaced: true, state, mutations, actions}

动态菜单和path都存好了以后我们就可以根据当前点击的path去动态的渲染我们的侧边栏啦

<!--src/layout/components/Sidebar/index.vue--><template> <div :class="{'has-logo':showLogo}"> <logo v-if="showLogo" :collapse="isCollapse" /> <el-scrollbar wrap-class="scrollbar-wrapper"> <el-menu :default-active="activeMenu" :collapse="isCollapse" :background-color="variables.menuBg" :text-color="variables.menuText" :unique-opened="false" :active-text-color="variables.menuActiveText" :collapse-transition="false" mode="vertical" > <sidebar-item v-for="route in menuList" :key="route.path" :item="route" :base-path="route.path" /> </el-menu> </el-scrollbar> </div></template><script>import { mapGetters } from 'vuex'import Logo from './Logo'import SidebarItem from './SidebarItem'import variables from '@/styles/variables.scss'export default { components: { SidebarItem, Logo }, computed: { ...mapGetters([ 'sidebar' ]), routes() { return this.$router.options.routes }, activeMenu() { const route = this.$route const { meta, path } = route // if set path, the sidebar will highlight the path you set if (meta.activeMenu) { return meta.activeMenu } return path }, showLogo() { return this.$store.state.settings.sidebarLogo }, variables() { return variables }, isCollapse() { return !this.sidebar.opened } }, watch: { // 因为每次点击顶部菜单的时候path都会改变,所以我们要对它进行监听; // 通过数组的filter方法去过滤出来我们想要的菜单数组就可以啦。 '$store.state.user.path': { handler: function(newVal, oldVal) { console.log('新值' + newVal, '旧值' + oldVal) console.log('vuex里存的菜单', this.$store.state.user.menuList) this.menuList = this.$store.state.user.menuList.filter(v => { return newVal === v.path }) } } }, mounted() { // 页面渲染时候获取一下vuex里的menuList,因为刚才在vuex里定义的path默认给了'/'; // 所以第一次进来的时候默认显示的首页 console.log('当前path', this.$store.state.user.path) this.$store.dispatch('user/setMenuList', this.$router.options.routes) this.menuList = this.$store.state.user.menuList.filter(v => { return this.$store.state.user.path === v.path }) }, // eslint-disable-next-line vue/order-in-components data() { return { menuList: [] } }}</script>🌟最后

当我们接到新需求的时候,一定要仔细分析把逻辑梳理清楚了;复杂的话我们可以画一下流程图以便我们更好的去写代码;万变不离其宗,思路最重要。小伙伴们如果有更好的思路,可以一起交流,共同进步。

✨原创不易,还希望各位大佬支持一下! 👍 点赞,你的认可是我创作的动力! ⭐️ 收藏,你的青睐是我努力的方向! ✏️ 评论,你的意见是我进步的财富!

本文链接地址:https://www.jiuchutong.com/zhishi/294530.html 转载请保留说明!

上一篇:雷斯岬国家海岸公园里的柏树隧道,美国加利福尼亚州 (© Spondylolithesis/Getty Images)(雷斯岬国家海岸公园有信号吗)

下一篇:ERR_FAILED 200 解决方案(err03 failed to)

  • 苹果手机口罩面部如何解锁(苹果手机口罩面部识别怎么设置)

    苹果手机口罩面部如何解锁(苹果手机口罩面部识别怎么设置)

  • pixiv18+怎么开(pixiv如何开启18+)

    pixiv18+怎么开(pixiv如何开启18+)

  • 如何解除word文档保护密码(如何解除word文档锁定的内容)

    如何解除word文档保护密码(如何解除word文档锁定的内容)

  • 苹果11系列是5G手机吗(苹果11系列是双扬声器吗)

    苹果11系列是5G手机吗(苹果11系列是双扬声器吗)

  • 支付宝运动与健身权限怎么开启(支付宝运动与健身)

    支付宝运动与健身权限怎么开启(支付宝运动与健身)

  • 华为p30pro电池不耐用(华为p30pro电池不耐用是更换电池还是用背夹电池)

    华为p30pro电池不耐用(华为p30pro电池不耐用是更换电池还是用背夹电池)

  • 戴尔电脑开机后进不了系统怎么办(戴尔电脑开机后一直响)

    戴尔电脑开机后进不了系统怎么办(戴尔电脑开机后一直响)

  • hp126a用什么型号硒鼓(hp126w)

    hp126a用什么型号硒鼓(hp126w)

  • 华为开了移动数据没有网络(华为开了移动数据没有网络怎么回事)

    华为开了移动数据没有网络(华为开了移动数据没有网络怎么回事)

  • 打电话一直播叫的用户正忙(打着电话看直播,对方能听到吗)

    打电话一直播叫的用户正忙(打着电话看直播,对方能听到吗)

  • 华为手机显示桌面布局已锁定怎么办(华为手机显示桌面图标在哪里)

    华为手机显示桌面布局已锁定怎么办(华为手机显示桌面图标在哪里)

  • 美团众包提现到账时间(美团众包提现到哪里)

    美团众包提现到账时间(美团众包提现到哪里)

  • ipadpro2020蜂窝版什么时候发售(ipadpro2020蜂窝版可以发短信吗)

    ipadpro2020蜂窝版什么时候发售(ipadpro2020蜂窝版可以发短信吗)

  • 欧版苹果和国行有什么区别(欧版苹果和美版区别)

    欧版苹果和国行有什么区别(欧版苹果和美版区别)

  • qq漂流瓶怎么没有了(qq漂流瓶不能用了,又有什么新的功能)

    qq漂流瓶怎么没有了(qq漂流瓶不能用了,又有什么新的功能)

  • 快手怎么删自己的动态(快手怎么删自己的评论图片)

    快手怎么删自己的动态(快手怎么删自己的评论图片)

  • 组织结构设计的影响因素(组织结构设计的关键要素包括)

    组织结构设计的影响因素(组织结构设计的关键要素包括)

  • 怎么生成wsdl文件(如何生成word文档)

    怎么生成wsdl文件(如何生成word文档)

  • 手机为什么下载不了抖音(手机为什么下载不了应用宝)

    手机为什么下载不了抖音(手机为什么下载不了应用宝)

  • 手机版微博id在哪儿(手机版微博id在哪里找)

    手机版微博id在哪儿(手机版微博id在哪里找)

  • 美图秀秀如何抠图手机(美图秀秀如何抠图人像)

    美图秀秀如何抠图手机(美图秀秀如何抠图人像)

  • 华为mate20黑屏显示时间日期(mate20突然黑屏)

    华为mate20黑屏显示时间日期(mate20突然黑屏)

  • 虚拟机上Linux如何获取主机Windows 7上文件?(linux虚拟机在哪里输入命令)

    虚拟机上Linux如何获取主机Windows 7上文件?(linux虚拟机在哪里输入命令)

  • 基于Vue的在线购物系统的设计与实现(论文+源码)_kaic(基于vue的网上商城)

    基于Vue的在线购物系统的设计与实现(论文+源码)_kaic(基于vue的网上商城)

  • 【论文导读】 - 关于联邦图神经网络的3篇文章(论文 导论)

    【论文导读】 - 关于联邦图神经网络的3篇文章(论文 导论)

  • 人类记忆系统之谜,也许就是这么回事儿(人类记忆存储在哪)

    人类记忆系统之谜,也许就是这么回事儿(人类记忆存储在哪)

  • 企业所得税研发费用加计扣除条件
  • 跨年度的租金收入如何入账
  • 固定资产什么时候开始折旧
  • 厂部管理人员薪酬计入什么费用
  • 增值税留抵税务处理办法
  • 小规模纳税人分红税率
  • 报销用专票
  • 机票抵扣进项只能在发生当月吗
  • 进口代理费取费标准
  • 固定资产报废会议记录怎么写
  • 应收账款因质量不符合退货应该实施什么审计程序
  • 汇算清缴前取得暂估发票
  • 计提工资数大于实际支付数怎么办?
  • 企业会计做无票收入也要交税吗?
  • 新公司第一个月报税怎么弄
  • 借款合同印花税减免优惠政策
  • 城镇土地使用税征收标准及计算方法
  • 残疾人收到房租租赁发票收入还要缴纳个税吗
  • 航天信息开票步骤
  • 运输企业营改增
  • 个人所得税的申报税额是什么意思
  • 税务局的网站以后有这些变化是你不知道的!
  • 应付和预付账款的区别
  • 赊销方式何时确认收入呢
  • 培训费开发票明细为会议费如何做账?
  • 2020工会经费退费
  • 印花税不足1元 需要计提吗
  • 公司租房中介费能报销吗
  • win10如何查看显卡配置
  • 在windows 7中
  • php字符串操作函数
  • PHP:apache_response_headers()的用法_Apache函数
  • 营改增建筑企业增值税
  • 如何通过利润表看企业收益
  • 为什么筹建期间的开办费不属于资产
  • php的lamp
  • php数组数据结构
  • thinkphp curl
  • Vue3通透教程【十三】TS简单类型详解
  • 处置固定资产涉税
  • dedecms插件
  • 土地出让金相关政策
  • 外购产品捐赠
  • 贷款计入什么科目
  • 委托代销业务的会计分录
  • 电费可以计入营业外收入吗
  • 营业外收入在汇算清缴里填哪张表
  • 应收账款无法收回说明模板
  • 结转增值税的账务处理一定要通过转出未交增值税吗
  • 防伪税控技术服务费减免的文件
  • 租赁费计提印花税税率
  • 一家公司一定要有一个社保吗
  • sql怎么比较两个表字段的内容
  • assoc.exe=exefile什么意思
  • 电脑xp系统如何
  • windows7如何关闭夜间模式
  • centos 添加服务
  • win7 系统没有声音
  • win7系统运行红警黑屏有声音
  • bzip2 bunzip2 bzcat参数使用
  • 在Linux系统中安装pacman
  • linux中命令行
  • jquery移动div到另一个div中
  • shell脚本用法
  • word文件排序乱怎么恢复
  • 缓动函数网站
  • node用什么写的
  • eclipse窗口显示设置
  • python urllib urlopen
  • jquery返回顶部代码
  • js访问thymeleaf值
  • 国家税务总局关于个人所得税有关政策问题的通知
  • 地方税务局怎么查企业信息
  • 银行和税务局的关系
  • 保险免保费是什么意思
  • 风险研判能力不足的原因
  • 组织生活会有民族评议党员大会会后报告
  • 小米之家可以
  • 国家重大水利工程建设基金征收标准
  • 国际贸易争端的形式
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设