Vue2项目练手——通用后台管理项目第八节

Vue2项目练手——通用后台管理项目

  • 菜单权限功能
    • tab.js
    • Login.vue
    • CommonAside.vue
    • router/index.js
  • 权限管理问题解决
    • router/tab.js
    • CommonHeader.vue
    • main.js

菜单权限功能

  1. 不同的账号登录,会有不同的菜单权限
  2. 通过url输入地址来显示页面
  3. 对于菜单的数据在不同页面之间的数据通信

tab.js

import Cookie from "js-cookie";
export default {state:{menu:[]},mutations:{//设置menu的数据setMenu(state,val){state.menu=valconsole.log("val",val)Cookie.set('menu',JSON.stringify(val))},//动态注册路由addMenu(state,router){//判断缓存中是否有数据if(!Cookie.get('menu')) returnconst menu=JSON.parse(Cookie.get('menu'))state.menu=menu//组装动态路由的数据const menuArray=[]menu.forEach(item=>{if(item.children){item.children= item.children.map(item=>{item.component=()=>import(`../pages/${item.url}`)return item})menuArray.push(...item.children)}else{item.component=()=>import(`../pages/${item.url}`)menuArray.push(item)}})console.log("menuArray",menuArray)//路由的动态添加menuArray.forEach(item=>{router.addRoute('main',item)})console.log("menuArray",menuArray)}}

全部代码:

import Cookie from "js-cookie";
export default {state:{isCollapse:false,  //控制菜单的展开还是收起tabsList:[{path:'/',name:"home",label:"首页",icon:"s-home",url:'Home/Home'},],  //面包屑数据menu:[]},mutations:{//   修改菜单展开收起的方法collapseMenu(state){state.isCollapse=!state.isCollapse},//更新面包屑selectMenu(state,val){//判断添加的数据是否为首页if(val.name!=='home'){// console.log("state",state)const index=state.tabsList.findIndex(item=>item.name===val.name)//如果不存在if(index===-1){state.tabsList.push(val)}}},//删除指定的tagcloseTag(state,item){const index=state.tabsList.findIndex(val=>val.name===item.name)state.tabsList.splice(index,1)   //splice(删除的位置,删除的个数)},//设置menu的数据setMenu(state,val){state.menu=valconsole.log("val",val)Cookie.set('menu',JSON.stringify(val))},//动态注册路由addMenu(state,router){//判断缓存中是否有数据if(!Cookie.get('menu')) returnconst menu=JSON.parse(Cookie.get('menu'))state.menu=menu//组装动态路由的数据const menuArray=[]menu.forEach(item=>{if(item.children){item.children= item.children.map(item=>{item.component=()=>import(`../pages/${item.url}`)return item})menuArray.push(...item.children)}else{item.component=()=>import(`../pages/${item.url}`)menuArray.push(item)}})console.log("menuArray",menuArray)//路由的动态添加menuArray.forEach(item=>{router.addRoute('main',item)})console.log("menuArray",menuArray)}}
}

Login.vue

getMenu(this.form).then(({data})=>{console.log(data)if(data.code===20000){Cookie.set('token',data.data.token)//获取菜单的数据,存入store中this.$store.commit('setMenu',data.data.menu)this.$store.commit('addMenu',this.$router)//跳转到首页this.$router.push('/home')}else{this.$message.error(data.data.message)}})

全部代码:

<template><div id="app"><div class="main-content"><div class="title">系统登录</div><div class="content"><el-form label-width="70px" :inline="true" :model="form" status-icon :rules="rules" ref="ruleForm" class="demo-ruleForm"><el-form-item label="用户名" prop="username"><el-input v-model="form.username" placeholder="请输入账号"></el-input></el-form-item><el-form-item label="密码" prop="password"><el-input v-model="form.password" type="password" autocomplete="off" placeholder="请输入密码"></el-input></el-form-item><el-form-item><el-button type="primary" @click="submitForm('ruleForm')">登录</el-button></el-col></el-form-item></el-form></div></div></div></template><script>
// import Mock from 'mockjs'
import Cookie from 'js-cookie'
import {getMenu} from "@/api";
export default {name: "login",data(){return{form: {username: '',password:""},rules: {username: [{required: true, message: '请输入用户名', trigger: 'blur'},],password: [{required:true,message:"请输入密码",trigger:"blur"}]}}},methods:{//登录submitForm(formName) {this.$refs[formName].validate((valid) => {if (valid) {//token信息/*const token=Mock.Random.guid()  //生成随机数//token信息存入cookie用于不同页面间的通信Cookie.set('token',token)*/getMenu(this.form).then(({data})=>{console.log(data)if(data.code===20000){Cookie.set('token',data.data.token)//获取菜单的数据,存入store中this.$store.commit('setMenu',data.data.menu)this.$store.commit('addMenu',this.$router)//跳转到首页this.$router.push('/home')}else{this.$message.error(data.data.message)}})} else {console.log('error submit!!');return false;}});},}
}
</script><style lang="less" scoped>
#app {display: flex;background-color: #333;height: 100vh;.main-content{height: 300px;width: 350px;//line-height: 100vh;background-color: #fff;margin: 200px auto;border-radius: 15px;padding: 35px 35px 15px 35px;box-sizing: border-box;box-shadow: 5px  5px 10px rgba(0,0,0,0.5),-5px -5px 10px rgba(0,0,0,0.5);.title{font-size: 20px;text-align: center;font-weight: 300;}.content{margin-top: 30px;}.el-input{width: 198px;}.el-button{margin-left: 105px;}}
}
</style>

CommonAside.vue

data() {return {};},
menuData(){//判断当前数据,如果缓存中没有,当前store中获取return JSON.parse(Cookie.get('menu'))||this.$store.state.tab.menu}

全部代码:

<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>{{isCollapse?'后台':'通用后台管理系统'}}</h3><el-menu-item @click="clickMenu(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 :index="item.label" v-for="item in hasChildren" :key="item.label"><template slot="title"><i :class="`el-icon-${item.icon}`"></i><span slot="title">{{item.label}}</span></template><el-menu-item-group><el-menu-item @click="clickMenu(subItem)" :index="subItem.path" :key="subItem.path" v-for="subItem in item.children">{{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;  //占据页面高度100%h3{color: #fff;text-align: center;line-height: 48px;font-size: 16px;font-weight: 400;}
}
</style><script>
import Cookie  from "js-cookie";
export default {data() {return {};},methods: {handleOpen(key, keyPath) {console.log(key, keyPath);},handleClose(key, keyPath) {console.log(key, keyPath);},clickMenu(item){// console.log(item)// console.log(this.$route.path)// 当页面的路由与跳转的路由不一致才允许跳转if(this.$route.path!==item.path && !(this.$route.path==='/home'&&(item.path==='/'))){this.$router.push(item.path)}this.$store.commit('selectMenu',item)}},mounted() {// console.log(this.$route.path)},computed:{//没有子菜单的数据noChildren(){return this.menuData.filter(item=>!item.children)},//有子菜单数组hasChildren(){return this.menuData.filter(item=>item.children)},isCollapse(){return this.$store.state.tab.isCollapse},menuData(){//判断当前数据,如果缓存中没有,当前store中获取return JSON.parse(Cookie.get('menu'))||this.$store.state.tab.menu}}
}
</script>

router/index.js

{// 子路由name:"main",path:'/',redirect:"/home",  //重定向 当路径为/,则重定向homecomponent:Main,children:[/*{name:"user",path:"user",component:User,meta:{title:"用户管理"}},{name:"home",path:"home",component:Home,meta:{title:"首页"}},{name:"mall",path:"mall",component:Mall,meta:{title:"商品管理"}},{name:"page1",path:"page1",component:PageOne,meta:{title:"页面1"}},{name:"page2",path:"page2",component:PageTwo,meta:{title:"页面2"}}*/]}

全部代码:

import VueRouter from "vue-router";
import Login from "@/pages/Login.vue";
import Main from '@/pages/Main.vue';
import User from "@/pages/User.vue";
import Home from "@/pages/Home.vue";
import Mall from "@/pages/Mall.vue";
import PageOne from "@/pages/PageOne.vue";
import PageTwo from "@/pages/PageTwo.vue";
import Cookie from "js-cookie";const router= new VueRouter({// 浏览器模式设置,设置为history模式// mode:'history',routes:[{name:'login',path:"/login",component:Login,meta:{title:"登录"},},{// 子路由name:"main",path:'/',redirect:"/home",  //重定向 当路径为/,则重定向homecomponent:Main,children:[/*{name:"user",path:"user",component:User,meta:{title:"用户管理"}},{name:"home",path:"home",component:Home,meta:{title:"首页"}},{name:"mall",path:"mall",component:Mall,meta:{title:"商品管理"}},{name:"page1",path:"page1",component:PageOne,meta:{title:"页面1"}},{name:"page2",path:"page2",component:PageTwo,meta:{title:"页面2"}}*/]}]
})
//添加全局前置导航守卫
router.beforeEach((to,from,next)=>{//判断token存不存在const token=Cookie.get('token')//token不存在,说明当前用户是未登录,应该跳转至登录页if(!token&&to.name!=='login'){next({name:'login'})}else if(token && to.name=="login"){   //token存在,说明用户登录,此时跳转至首页next({name:'home'})}else{next()}
})
// 后置路由守卫
router.afterEach((to,from)=>{document.title=to.meta.title||"通用后台管理系统"
})
export default router

请添加图片描述

权限管理问题解决

router/tab.js

clearTabs(state){//清除除过首页之外的所有面包屑state.tabsList=state.tabsList.splice(0,1)}

全部代码:

import Cookie from "js-cookie";
export default {state:{isCollapse:false,  //控制菜单的展开还是收起tabsList:[{path:'/',name:"home",label:"首页",icon:"s-home",url:'Home/Home'},],  //面包屑数据menu:[]},mutations:{//   修改菜单展开收起的方法collapseMenu(state){state.isCollapse=!state.isCollapse},//更新面包屑selectMenu(state,val){//判断添加的数据是否为首页if(val.name!=='home'){// console.log("state",state)const index=state.tabsList.findIndex(item=>item.name===val.name)//如果不存在if(index===-1){state.tabsList.push(val)}}},//删除指定的tagcloseTag(state,item){const index=state.tabsList.findIndex(val=>val.name===item.name)state.tabsList.splice(index,1)   //splice(删除的位置,删除的个数)},//设置menu的数据setMenu(state,val){state.menu=valconsole.log("val",val)Cookie.set('menu',JSON.stringify(val))},//动态注册路由addMenu(state,router){//判断缓存中是否有数据if(!Cookie.get('menu')) returnconst menu=JSON.parse(Cookie.get('menu'))state.menu=menu//组装动态路由的数据const menuArray=[]menu.forEach(item=>{if(item.children){item.children= item.children.map(item=>{item.component=()=>import(`../pages/${item.url}`)return item})menuArray.push(...item.children)}else{item.component=()=>import(`../pages/${item.url}`)menuArray.push(item)}})console.log("menuArray",menuArray)//路由的动态添加menuArray.forEach(item=>{router.addRoute('main',item)})console.log("menuArray",menuArray)},clearTabs(state){//清除除过首页之外的所有面包屑state.tabsList=state.tabsList.splice(0,1)}}
}

CommonHeader.vue

handleClick(command){if(command==='cancel'){console.log("登出")//清除Cookie的token信息Cookie.remove('token')//清除cookie中的menuCookie.remove('menu')this.$store.commit('clearTabs')this.$router.push('/login')}}

全部代码:

<template><div class="header-container"><div class="l-content"><el-button style="margin-right: 20px" icon="el-icon-menu" size="mini" @click="handleMenu"></el-button><!--      面包屑-->
<!--      <span class="text">首页</span>--><el-breadcrumb separator="/"><el-breadcrumb-item v-for="item in tags" :key="item.path" :to="{ path: item.path }">{{ item.label }}</el-breadcrumb-item></el-breadcrumb></div><div class="r-content"><el-dropdown @command="handleClick"><span class="el-dropdown-link"><img src="@/assets/user.webp" alt=""></span><el-dropdown-menu slot="dropdown"><el-dropdown-item>个人中心</el-dropdown-item><el-dropdown-item command="cancel">退出</el-dropdown-item></el-dropdown-menu></el-dropdown></div></div></template><script>
import {mapState} from 'vuex'
import Cookie from 'js-cookie'
export default {name: "CommonHeader",methods:{handleMenu(){this.$store.commit('collapseMenu')},handleClick(command){if(command==='cancel'){console.log("登出")//清除Cookie的token信息Cookie.remove('token')//清除cookie中的menuCookie.remove('menu')this.$store.commit('clearTabs')this.$router.push('/login')}}},computed:{...mapState({tags: state=>state.tab.tabsList})}
}
</script><style scoped lang="less">
.header-container {height: 60px;background-color: #333;display: flex;justify-content: space-between;align-items: center;padding: 0 20px;.text {color: #fff;font-size: 14px;margin-left: 10px;}.r-content{img{width: 40px;height: 40px;border-radius: 50%;}}.l-content{display: flex;align-items: center;/deep/.el-breadcrumb__item{   /*元素没有绑定data-v-5a90ec03这样的编号时候,样式不起作用,使用deep进行穿刺可解决问题*/.el-breadcrumb__inner{font-weight: normal;&.is-link{color: #666;}}&:last-child{.el-breadcrumb__inner {color: #fff;}}}}
}
</style>

main.js

created(){store.commit('addMenu',router)}

全部代码:

import Vue from 'vue'
import App from './App.vue'
import VueRouter from "vue-router";
import router from "@/router";
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css'
import store from '@/store'
//引入mock模拟
import '@/api/mock'Vue.config.productionTip = false
Vue.use(VueRouter)
Vue.use(ElementUI)
new Vue({store,router,render: h => h(App),created(){store.commit('addMenu',router)}
}).$mount('#app')

请添加图片描述

项目到此Vue2部分也就结束了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/103452.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何在`Pycharm`中配置基于WSL的`Python Interpreters`,以及配置基于WSL的`Terminal`

文章目录 一、创建pycharm用户并授予sudo权限0. 启动WSL下的CentOS1. 创建pycharm用户并授予sudo权限2. 设置pycharm用户为wsl启动Linux的默认用户3. 重启并重新登录wsl下的CentOS4. 验证pycharm用户的sudo权限 二、创建基于WSL的Python Interpreter1. 添加基于WSL的Python Int…

查看视频文件关键帧间隔

一、Elecard StreamEye Tools拖放视频文件查看。 红的是I帧&#xff1b;蓝的是P帧&#xff1b;绿的是B帧。 二、ffprobe -show_streams统计。 1、统计视频关键帧、非关键帧 ffprobe.exe -i 1.mp4 -show_streams v -show_packets -print_format json > d:\1.json 再统计1.j…

Greenplum执行SQL卡住的问题

问题 今天社区群里面一位同学反映他的SQL语句执行会hang住&#xff0c;执行截图如下。 分析 根据提示信息&#xff0c;判断可能是网络有问题&#xff0c;或者是跟GP使用UDP包有关系。 此同学找了网络检查的人确定网络没有问题&#xff0c;于是猜测跟UDP包有关。 参考文章ht…

Linux常用命令——convertquota命令

在线Linux命令查询工具 convertquota 把老的配额文件转换为新的格式 补充说明 convertquota命令用于将老的磁盘额数据文件&#xff08;“quota.user”和“quota.group”&#xff09;转换为新格式的文件&#xff08;“quota.user”和“quota.group”&#xff09;。 语法 c…

Vite + vue3 项目使用 amfe-flexible 和 postcss-pxtorem 实现不同屏幕自适应

amfe-flexible 和 postcss-pxtorem 可以一起使用来实现移动端的适配效果。 amfe-flexible 主要用于动态设置根元素字体大小&#xff08;rem&#xff09;&#xff0c;以根据屏幕尺寸进行自适应布局。它会根据设备的屏幕宽度计算出根元素字体大小&#xff0c;并将其设置为页面的根…

微信小程序使用 scss

一、在 vscode 中安装 easy sass 扩展 二、在微信开发者工具导入 vscode 安装的 easy sass 扩展 安装完成后会让重新加载扩展 再次打开后就可以看到扩展已经有 easy sass 了 三、修改 easy sass 配置 重新加载扩展后&#xff0c;默认情况下这个扩展是已经启动的&#xff0c…

无涯教程-JavaScript - IMLOG10函数

描述 IMLOG10函数以x yi或x yj文本格式返回复数的公共对数(以10为底)。可以从自然对数计算复数的公共对数,如下所示: $$\log_ {10}(x yi)(\log_ {10} e)\ln(x yi)$$ 语法 IMLOG10 (inumber)争论 Argument描述Required/OptionalInumberA complex number for which you …

数据可视化:四大发明的现代转化引擎

在科技和工业的蓬勃发展中&#xff0c;中国的四大发明——造纸术、印刷术、火药和指南针&#xff0c;早已不再是古代创新的象征&#xff0c;而是催生了众多衍生行业的崭新可能性。其中&#xff0c;数据可视化技术正成为这些行业的一颗璀璨明珠&#xff0c;开启了全新的时代。 1…

Apache DolphinScheduler - 快速扩展 TaskPlugin 从入门到放弃

目前在大数据生态中&#xff0c;调度系统是不可或缺的一个重要组件。Apache DolphinScheduler 作为一个顶级的 Apache 项目&#xff0c;其稳定性和易用性也可以说是名列前茅的。而对于一个调度系统来说&#xff0c;能够支持的可调度的任务类型同样是一个非常重要的因素&#xf…

centos7使用docker-compose一键搭建mysql高可用主从集群

docker部署 环境准备 卸载旧版本 yum remove -y docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-selinux \docker-engine-selinux \docker-engine 安装依赖 yum install -y yum-utils \…

命令执行漏洞复现攻击:识别威胁并加强安全

环境准备 这篇文章旨在用于网络安全学习&#xff0c;请勿进行任何非法行为&#xff0c;否则后果自负。 一、攻击相关介绍 原理 主要是输入验证不严格、代码逻辑错误、应用程序或系统中缺少安全机制等。攻击者可以通过构造特定的输入向应用程序或系统注入恶意代码&#xff…

广电运营商三网融合监控运维方案

随着三网融合逐步发展、深化&#xff0c;广电网络从为用户提供原本单一的信息服务转向了集语音、文字、图像为一体的信息服务&#xff0c;同时也实现了由单一独立的网络向综合性网络的改变。如何在业务的融合与竞争中创造核心竞争力&#xff0c;利用自身网络覆盖率上的优势&…