一、项目效果

二、项目版本,技术栈

node.js 16.16.0

vue-cli 5.0.8

vue-router 3.6.5

技术栈:vue2,vuex,element-ui,ajax,js-cookie,mockjs

三、配置vue-router3

下载vue-router,地址安装 | Vue Router

yarn add vue-router@3.6.5

在src的router目录下创建index.js,引入vue-router

四、下载预处理器stylus,stylus-loader

yarn stylus stylus-loader@5.0.0

关闭eslint

五、设置嵌套路由

六、element-ui按需引入

npm i element-ui -S

npm install babel-plugin-component -D

注意message消息提示,调用方法和其他组件不同

七、首页布局,main组件引入container

element-ui网址 Element - The world's most popular Vue UI framework

选择倒数第二个布局

八、侧边栏commonAside菜单

侧边栏是公共组件,放在components中

调整成我们想要的效果

<template><div><el-menudefault-active="2"class="el-menu-vertical-demo"@open="handleOpen"@close="handleClose"background-color="#545c64"text-color="#fff"active-text-color="#ffd04b"><h3>通用后台管理系统</h3><el-menu-item index="2"><i class="el-icon-menu"></i><span slot="title">导航二</span></el-menu-item><el-menu-item index="3"><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>导航一</span></template><el-menu-item-group><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></div>
</template><script>export default {methods: {handleOpen(key, keyPath) {console.log(key, keyPath);},handleClose(key, keyPath) {console.log(key, keyPath);}}}
</script><style lang="stylus" scoped>
.el-menuheight: 100vhborder-right: nonecolor #fffh3color: #ffftext-align: centerline-height: 48pxfont-size: 16pxfont-weight: 400
</style>

去掉白边

创建menuData数组,判断有无子菜单,遍历侧边栏菜单

<template><div><el-menudefault-active="2"class="el-menu-vertical-demo"@open="handleOpen"@close="handleClose"background-color="#545c64"text-color="#fff"active-text-color="#ffd04b"><h3>通用后台管理系统</h3><el-menu-item:index="item.name"v-for="item in noChildren":key="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>{{item.label}}</span></template><el-menu-item-groupv-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></div>
</template><script>
export default {data () {return {menuData: [{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'}]}]}},computed: {noChildren () {return this.menuData.filter(item => !item.children)},hasChildren () {return this.menuData.filter(item => item.children)},},methods: {handleOpen(key, keyPath) {console.log(key, keyPath);},handleClose(key, keyPath) {console.log(key, keyPath);}}
}
</script><style lang="stylus" scoped>
.el-menuheight: 100vhborder-right: nonecolor #fffh3color: #ffftext-align: centerline-height: 48pxfont-size: 16pxfont-weight: 400
</style>

九、侧边栏路由实现

根据menuData里的path,在路由文件里配置路由

<template><div><el-menudefault-active="2"class="el-menu-vertical-demo"@open="handleOpen"@close="handleClose"background-color="#545c64"text-color="#fff"active-text-color="#ffd04b"><h3>通用后台管理系统</h3><el-menu-item:index="item.name"v-for="item in noChildren":key="item.name"@click="clickMenu(item)"><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>{{item.label}}</span></template><el-menu-item-groupv-for="subItem in item.children":key="subItem.name"><el-menu-item @click="clickMenu(subItem)" :index="subItem.name">{{subItem.label}}</el-menu-item></el-menu-item-group></el-submenu></el-menu></div>
</template><script>
export default {data () {return {menuData: [{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'}]}]}},computed: {noChildren () {return this.menuData.filter(item => !item.children)},hasChildren () {return this.menuData.filter(item => item.children)},},methods: {handleOpen(key, keyPath) {console.log(key, keyPath);},handleClose(key, keyPath) {console.log(key, keyPath);},clickMenu (item) {if (this.$route.path !== item.path && !(this.$route.path === '/home' && (item.path === '/'))) {this.$router.push(item.path)}console.log(item, 'item')}}
}
</script><style lang="stylus" scoped>
.el-menuheight: 100vhborder-right: nonecolor #fffh3color: #ffftext-align: centerline-height: 48pxfont-size: 16pxfont-weight: 400
</style>

头部制作

<template><div class="header"><div class="l-content"><el-button icon="el-icon-menu" size="small"></el-button><el-breadcrumb separator="/"><el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item><el-breadcrumb-item><a href="/">活动管理</a></el-breadcrumb-item><el-breadcrumb-item>活动列表</el-breadcrumb-item><el-breadcrumb-item>活动详情</el-breadcrumb-item></el-breadcrumb></div><div class="r-content"><el-dropdown><span class="el-dropdown-link"><img class="user-img" src="../assets/images/user.png"></span><el-dropdown-menu slot="dropdown"><el-dropdown-item>个人中心</el-dropdown-item><el-dropdown-item>退出</el-dropdown-item></el-dropdown-menu></el-dropdown></div></div>
</template><script>export default {}
</script><style lang="stylus" scoped>
.headerpadding: 0 20pxheight: 60pxbackground-color: #333display: flexjustify-content: space-betweenalign-items: center.l-contentdisplay: flexalign-items: center.r-content.user-imgwidth: 40pxheight: 40pxborder-radius: 50%
</style>

菜单折叠效果

vue2中,要用vuex的3版本
vue3中,要用vuex的4版本

yarn add vuex@3.6.2 --save

优化

home页面

layout布局

引入box-card

<template><div><el-row><el-col :span="8"><el-card class="box-card"></el-card><el-card class="box-card"></el-card></el-col><el-col :span="16"><div class="num"><el-card class="box-card"></el-card></div><el-card class="box-card"></el-card><div class="graph"><el-card class="box-card"></el-card></div></el-col></el-row></div>
</template><script>export default {}
</script><style scoped></style>

头像部分

<template><div><el-row><el-col :span="8"><el-card class="box-card" style="height: 285px; margin-bottom: 20px;"><div class="user"><img src="@/assets/images/user.png" /><div class="user-info"><div class="name">Admin</div><div class="access">超级管理员</div></div></div><div class="login"><p>上次登录时间:<span>2021-7-19</span></p><p>上次登录地点:<span>武汉</span></p></div></el-card><el-card class="box-card" style="height: 479px"></el-card></el-col><el-col :span="16"><div class="num"><el-card class="box-card"></el-card></div><el-card class="box-card"></el-card><div class="graph"><el-card class="box-card"></el-card></div></el-col></el-row></div>
</template><script>export default {}
</script><style lang="stylus" scoped>
.userdisplay flexborder-bottom: 1px solid #cccpadding-bottom: 20pximgmargin-right 40pxwidth 150pxheight: 150pxborder-radius: 50%.user-infopadding 35px 20px 20px 20px.namefont-size: 32pxmargin-bottom: 10px.accesscolor: #999
.loginpadding-top: 20pxpline-height: 28pxfont-size: 14pxcolor: #999spancolor: #666666;margin-left: 60px;
</style>

统计购买部分

<template><div><el-row><el-col :span="8"><el-card class="box-card" style="height: 285px; margin-bottom: 20px;"><div class="user"><img src="@/assets/images/user.png" /><div class="user-info"><div class="name">Admin</div><div class="access">超级管理员</div></div></div><div class="login"><p>上次登录时间:<span>2021-7-19</span></p><p>上次登录地点:<span>武汉</span></p></div></el-card><el-card class="box-card" style="height: 479px"><el-table:data="tableData"stripestyle="width: 100%"><el-table-column:prop="key":label="val"v-for="(val, key) in tableLabel"></el-table-column></el-table></el-card></el-col><el-col :span="16"><div class="num"><el-card class="box-card"></el-card></div><el-card class="box-card"></el-card><div class="graph"><el-card class="box-card"></el-card></div></el-col></el-row></div>
</template><script>export default {data () {return {tableData: [{name: 'oppo',todayBuy: 100,monthBuy: 300,totalBuy: 800},{name: 'vivo',todayBuy: 100,monthBuy: 300,totalBuy: 800},{name: '苹果',todayBuy: 100,monthBuy: 300,totalBuy: 800},{name: '小米',todayBuy: 100,monthBuy: 300,totalBuy: 800},{name: '三星',todayBuy: 100,monthBuy: 300,totalBuy: 800},{name: '魅族',todayBuy: 100,monthBuy: 300,totalBuy: 800}],tableLabel: {name: "课程",todayBuy: "今日购买",monthBuy: "本月购买",totalBuy: "总购买"}}}}
</script><style lang="stylus" scoped>
.userdisplay flexborder-bottom: 1px solid #cccpadding-bottom: 20pximgmargin-right 40pxwidth 150pxheight: 150pxborder-radius: 50%.user-infopadding 35px 20px 20px 20px.namefont-size: 32pxmargin-bottom: 10px.accesscolor: #999
.loginpadding-top: 20pxpline-height: 28pxfont-size: 14pxcolor: #999spancolor: #666666;margin-left: 60px;
</style>

订单统计部分

countData

countData: [{name: "今日支付订单",value: 1234,icon: "success",color: "#2ec7c9",},{name: "今日收藏订单",value: 210,icon: "star-on",color: "#ffb980",},{name: "今日未支付订单",value: 1234,icon: "s-goods",color: "#5ab1ef",},{name: "本月支付订单",value: 1234,icon: "success",color: "#2ec7c9",},{name: "本月收藏订单",value: 210,icon: "star-on",color: "#ffb980",},{name: "本月未支付订单",value: 1234,icon: "s-goods",color: "#5ab1ef",},],

<template><div><el-row><el-col :span="8"><el-card class="box-card" style="height: 285px; margin-bottom: 20px;"><div class="user"><img src="@/assets/images/user.png" /><div class="user-info"><div class="name">Admin</div><div class="access">超级管理员</div></div></div><div class="login"><p>上次登录时间:<span>2021-7-19</span></p><p>上次登录地点:<span>武汉</span></p></div></el-card><el-card class="box-card" style="height: 479px"><el-table:data="tableData"stripestyle="width: 100%"><el-table-column:prop="key":label="val"v-for="(val, key) in tableLabel"></el-table-column></el-table></el-card></el-col><el-col :span="16"><div class="num"><el-card class="box-card"v-for="item in countData":key="item.name":body-style="{display: 'flex', padding: 0}"><i class="icon" :class="`el-icon-${item.icon}`":style="{background: item.color}"></i><div class="detail"><p class="price">¥ {{item.value}}</p><p class="desc">{{item.name}}</p></div></el-card></div><el-card class="box-card"></el-card><div class="graph"><el-card class="box-card"></el-card></div></el-col></el-row></div>
</template><script>export default {data () {return {tableData: [{name: 'oppo',todayBuy: 100,monthBuy: 300,totalBuy: 800},{name: 'vivo',todayBuy: 100,monthBuy: 300,totalBuy: 800},{name: '苹果',todayBuy: 100,monthBuy: 300,totalBuy: 800},{name: '小米',todayBuy: 100,monthBuy: 300,totalBuy: 800},{name: '三星',todayBuy: 100,monthBuy: 300,totalBuy: 800},{name: '魅族',todayBuy: 100,monthBuy: 300,totalBuy: 800}],tableLabel: {name: "课程",todayBuy: "今日购买",monthBuy: "本月购买",totalBuy: "总购买"},countData: [{name: "今日支付订单",value: 1234,icon: "success",color: "#2ec7c9",},{name: "今日收藏订单",value: 210,icon: "star-on",color: "#ffb980",},{name: "今日未支付订单",value: 1234,icon: "s-goods",color: "#5ab1ef",},{name: "本月支付订单",value: 1234,icon: "success",color: "#2ec7c9",},{name: "本月收藏订单",value: 210,icon: "star-on",color: "#ffb980",},{name: "本月未支付订单",value: 1234,icon: "s-goods",color: "#5ab1ef",},],}}}
</script><style lang="stylus" scoped>
.userdisplay flexborder-bottom: 1px solid #cccpadding-bottom: 20pximgmargin-right 40pxwidth 150pxheight: 150pxborder-radius: 50%.user-infopadding 35px 20px 20px 20px.namefont-size: 32pxmargin-bottom: 10px.accesscolor: #999
.loginpadding-top: 20pxpline-height: 28pxfont-size: 14pxcolor: #999spancolor: #666666;margin-left: 60px;
.numdisplay: flexflex-wrap: wrap.el-cardmargin-left: 20pxwidth: 30.4%margin-bottom: 20px.iconwidth 80pxheight 80pxline-height 80pxfont-size 30pxtext-align centercolor #fff.detailmargin-left 15pxdisplay flexflex-direction columnjustify-content center.pricefont-size 30pxmargin-bottom 10pxline-height 30pxheight 30px.descfont-size 14pxcolor #999text-align center
</style>

ajax

yarn add axios@0.27.2

封装ajax

axios中文文档|axios中文网 | axios

定义一个请求首页数据的接口

在页面中可以调用

yarn add mockjs@1.1.0

home.js

// mock数据模拟
import Mock from 'mockjs'// 图表数据
let List = []
export default {getStatisticalData: () => {//Mock.Random.float 产生随机数100到8000之间 保留小数 最小0位 最大0位for (let i = 0; i < 7; i++) {List.push(Mock.mock({苹果: Mock.Random.float(100, 8000, 0, 0),vivo: Mock.Random.float(100, 8000, 0, 0),oppo: Mock.Random.float(100, 8000, 0, 0),魅族: Mock.Random.float(100, 8000, 0, 0),三星: Mock.Random.float(100, 8000, 0, 0),小米: Mock.Random.float(100, 8000, 0, 0)}))}return {code: 20000,data: {// 饼图videoData: [{name: '小米',value: 2999},{name: '苹果',value: 5999},{name: 'vivo',value: 1500},{name: 'oppo',value: 1999},{name: '魅族',value: 2200},{name: '三星',value: 4500}],// 柱状图userData: [{date: '周一',new: 5,active: 200},{date: '周二',new: 10,active: 500},{date: '周三',new: 12,active: 550},{date: '周四',new: 60,active: 800},{date: '周五',new: 65,active: 550},{date: '周六',new: 53,active: 770},{date: '周日',new: 33,active: 170}],// 折线图orderData: {date: ['20191001', '20191002', '20191003', '20191004', '20191005', '20191006', '20191007'],data: List},tableData: [{name: 'oppo',todayBuy: 500,monthBuy: 3500,totalBuy: 22000},{name: 'vivo',todayBuy: 300,monthBuy: 2200,totalBuy: 24000},{name: '苹果',todayBuy: 800,monthBuy: 4500,totalBuy: 65000},{name: '小米',todayBuy: 1200,monthBuy: 6500,totalBuy: 45000},{name: '三星',todayBuy: 300,monthBuy: 2000,totalBuy: 34000},{name: '魅族',todayBuy: 350,monthBuy: 3000,totalBuy: 22000}]}}}
}

购买统计数据替换

echarts折线图

yarn add echarts@5.1.2

在home页面引入echarts

import * as echarts from 'echarts';

柱状图

饼状图

<template><div><el-row><el-col :span="8"><el-card class="box-card" style="height: 285px; margin-bottom: 20px;"><div class="user"><img src="@/assets/images/user.png" /><div class="user-info"><div class="name">Admin</div><div class="access">超级管理员</div></div></div><div class="login"><p>上次登录时间:<span>2021-7-19</span></p><p>上次登录地点:<span>武汉</span></p></div></el-card><el-card class="box-card" style="height: 457px"><el-table:data="tableData"stripestyle="width: 100%"><el-table-column:prop="key":label="val"v-for="(val, key) in tableLabel"></el-table-column></el-table></el-card></el-col><el-col :span="16"><div class="num"><el-card class="box-card"v-for="item in countData":key="item.name":body-style="{display: 'flex', padding: 0}"><i class="icon" :class="`el-icon-${item.icon}`":style="{background: item.color}"></i><div class="detail"><p class="price">¥ {{item.value}}</p><p class="desc">{{item.name}}</p></div></el-card></div><el-card class="box-card" style="height: 280px;margin-left: 20px;"><div ref="echarts1" style="height: 280px;"></div></el-card><div class="graph"><el-card class="box-card" style="height: 260px;"><div ref="echarts2" style="height: 260px; width: 340px;"></div></el-card><el-card class="box-card" style="height: 260px;"><div ref="echarts3" style="height: 240px;width: 340px;"></div></el-card></div></el-col></el-row></div>
</template><script>import * as echarts from 'echarts';import { getData } from '../api'export default {data () {return {tableData: [],countData: [],tableLabel: {name: "课程",todayBuy: "今日购买",monthBuy: "本月购买",totalBuy: "总购买"}}},mounted() {getData().then(({ data }) => {console.log(data)const { tableData, countData } = data.datathis.tableData = tableDatathis.countData = countData// 基于准备好的dom,初始化echarts实例const echarts1 = echarts.init(this.$refs.echarts1)// 指定图表的配置项和数据var echarts1Option = {}// 处理数据xAxisconst { orderData, userData, videoData } = data.dataconst xAxis = Object.keys(orderData.data[0])const xAxisData = {data: xAxis}echarts1Option.xAxis = xAxisDataecharts1Option.yAxis = {}echarts1Option.legend = xAxisDataecharts1Option.series = []xAxis.forEach(key => {echarts1Option.series.push({name: key,data: orderData.data.map(item => item[key]),type: 'line'})})console.log(echarts1Option)// 使用刚指定的配置项和数据显示图表。echarts1.setOption(echarts1Option)// 柱状图const echarts2 = echarts.init(this.$refs.echarts2)const eachrts2Option = {legend: {// 图例文字颜色textStyle: {color: "#333",},},grid: {left: "20%",},// 提示框tooltip: {trigger: "axis",},xAxis: {type: "category", // 类目轴data: userData.map(item => item.date),axisLine: {lineStyle: {color: "#17b3a3",},},axisLabel: {interval: 0,color: "#333",},},yAxis: [{type: "value",axisLine: {lineStyle: {color: "#17b3a3",},},},],color: ["#2ec7c9", "#b6a2de"],series: [{name: '新增用户',data: userData.map(item => item.new),type: 'bar'},{name: '活跃用户',data: userData.map(item => item.active),type: 'bar'}],}echarts2.setOption(eachrts2Option)// 饼状图const echarts3 = echarts.init(this.$refs.echarts3)const eachrts3Option = {tooltip: {trigger: "item",},color: ["#0f78f4","#dd536b","#9462e5","#a6a6a6","#e1bb22","#39c362","#3ed1cf",],series: [{data: videoData,type: 'pie'}],}echarts3.setOption(eachrts3Option)})}}
</script><style lang="stylus" scoped>
.userdisplay flexborder-bottom: 1px solid #cccpadding-bottom: 20pximgmargin-right 40pxwidth 150pxheight: 150pxborder-radius: 50%.user-infopadding 35px 20px 20px 20px.namefont-size: 32pxmargin-bottom: 10px.accesscolor: #999
.loginpadding-top: 20pxpline-height: 28pxfont-size: 14pxcolor: #999spancolor: #666666;margin-left: 60px;
.numdisplay: flexflex-wrap: wrap.el-cardmargin-left: 20pxwidth: 30.4%margin-bottom: 20px.iconwidth 80pxheight 80pxline-height 80pxfont-size 30pxtext-align centercolor #fff.detailmargin-left 15pxdisplay flexflex-direction columnjustify-content center.pricefont-size 30pxmargin-bottom 10pxline-height 30pxheight 30px.descfont-size 14pxcolor #999text-align center
.graphdisplay: flexjustify-content: space-betweenmargin: 20px 0 0 20px
</style>

在tab里的state里定义关于面包屑数据

在mutation里定义一个方法selectMenu()用来更新面包屑数据

tabsList渲染面包屑

深拷贝

让其最后一个子元素是白色

tag标签

tag的删除功能和改变主题

解决删除后标签无高亮的问题

用户管理

dialog和form

表单验证

表单关闭数据清空

 

渲染table表格

新增一个user.js来存放和用户相关的mock模拟的数据

user.js

import Mock from 'mockjs'// get请求从config.url获取参数,post从config.body中获取参数
function param2Obj (url) {const search = url.split('?')[1]if (!search) {return {}}return JSON.parse('{"' +decodeURIComponent(search).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g, '":"') +'"}')
}let List = []
const count = 200for (let i = 0; i < count; i++) {List.push(Mock.mock({id: Mock.Random.guid(),name: Mock.Random.cname(),addr: Mock.mock('@county(true)'),'age|18-60': 1,birth: Mock.Random.date(),sex: Mock.Random.integer(0, 1)}))
}export default {/*** 获取列表* 要带参数 name, page, limt; name可以不填, page,limit有默认值。* @param name, page, limit* @return {{code: number, count: number, data: *[]}}*/getUserList: config => {const { name, page = 1, limit = 20 } = param2Obj(config.url)console.log('name:' + name, 'page:' + page, '分页大小limit:' + limit)const mockList = List.filter(user => {if (name && user.name.indexOf(name) === -1 && user.addr.indexOf(name) === -1) return falsereturn true})const pageList = mockList.filter((item, index) => index < limit * page && index >= limit * (page - 1))return {code: 20000,count: mockList.length,list: pageList}},/*** 增加用户* @param name, addr, age, birth, sex* @return {{code: number, data: {message: string}}}*/createUser: config => {const { name, addr, age, birth, sex } = JSON.parse(config.body)console.log(JSON.parse(config.body))List.unshift({id: Mock.Random.guid(),name: name,addr: addr,age: age,birth: birth,sex: sex})return {code: 20000,data: {message: '添加成功'}}},/*** 删除用户* @param id* @return {*}*/deleteUser: config => {const { id } = JSON.parse(config.body)if (!id) {return {code: -999,message: '参数不正确'}} else {List = List.filter(u => u.id !== id)return {code: 20000,message: '删除成功'}}},/*** 批量删除* @param config* @return {{code: number, data: {message: string}}}*/batchremove: config => {let { ids } = param2Obj(config.url)ids = ids.split(',')List = List.filter(u => !ids.includes(u.id))return {code: 20000,data: {message: '批量删除成功'}}},/*** 修改用户* @param id, name, addr, age, birth, sex* @return {{code: number, data: {message: string}}}*/updateUser: config => {const { id, name, addr, age, birth, sex } = JSON.parse(config.body)const sex_num = parseInt(sex)List.some(u => {if (u.id === id) {u.name = nameu.addr = addru.age = ageu.birth = birthu.sex = sex_numreturn true}})return {code: 20000,data: {message: '编辑成功'}}}
}

配置请求的接口

mock中添加模拟的数据接口

slot-scope="scope"作用域插槽,作用:可以在父组件中获取到子组件的数据

新增和修改

新增按钮和编辑按钮共用一个弹窗, modalType: 0,控制,0 新增,1 编辑

给新增按钮添加一个方法handAdd它的modalType = 0 , dialogVisible =true展开弹窗

给编辑按钮添加一个方法handleEdit,它的modalType = 1dialogVisible =true展开弹窗

封装getList方法

解决回显性别显示1和0的问题

查询和删除

 

删除按钮

分页功能

登录权限

yarn add js-cookie@3.0.1

token信息存入cookie用于不同页面的通信

在main.js里添加全局前置导航守卫

登录接口逻辑实现

引入permission.js

 在点击登录按钮的时候,判断这个code来判断账号密码是否正确,正确就跳转至首页,不正确就显示错误信息

个人中心退出按钮

菜单权限

1、不同账号的菜单权限
动态获取菜单栏路由数据

判断当前数据,cookie中没有就去store中获取

2、通过URL输入地址显示页面

router动态注册路由

重新登陆一下

看到这个输出就是成功了

删除之前写死的路由,并将跟路由改成 /home

解决空白页面的问题

笔记参考哔哩哔哩Allen前端vue后台管理系统笔记_杨白鹤的博客-CSDN博客哔哩哔哩Allen前端vue后台管理系统笔记https://blog.csdn.net/weixin_59820248/article/details/128590099

哔哩哔哩Allen老师通用后台管理系统相关推荐

  1. 哔哩哔哩Allen前端vue后台管理系统笔记

    哔哩哔哩Allen前端vue后台管理系统笔记 Element ui 引入 全局引入 按需引入 嵌套路由 左侧菜单栏的样式 Container布局,左侧菜单栏commonAside组件 commonAs ...

  2. 通用后台管理系统(ExtJS 4.2 + Spring MVC 3.2 + Hibernate)

    通用后台管理系统(ExtJS 4.2 +Spring MVC 3.2 + Hibernate) 开发语言JAVA 成品成品 前端技术extjs 数据库mysql,sql server,oracle 系 ...

  3. 【前端】Vue+Element UI案例:通用后台管理系统-用户管理:Table表格增删查改、Pagination分页、搜索框

    文章目录 目标 代码 0.结构 1.按钮-删除 2.按钮-编辑 3.debug 4.样式 5.分页Pagination:功能 6.分页Pagination:样式 7.搜索框:功能 8.搜索框:样式 总 ...

  4. 【前端】Vue+Element UI案例:通用后台管理系统-用户管理:Form表单填写、Dialog对话框弹出

    文章目录 目标 代码 0.页面结构 1.新增按钮和弹出表单:结构 2.新增按钮和弹出表单:点击新增弹出表单 3.表单样式 4.表单验证 5.表单的提交和取消功能:接口.mock相关准备 6.表单的提交 ...

  5. c#通用后台管理系统

    c#通用后台管理系统 C#通用后台管理系统 最近因公司工作需要,要编制一个小型的oa系统,在网上找了一下,发现大多数的功能都不是我们想用的,没办法,只好自己来写一个,开始写了个登录后,懒病又犯了,不想 ...

  6. Thinkphp 6 + Vue 2 + ElementUI + Vxe-table 前后端分离的,一键生成代码和API接口的,通用后台管理系统 快速开发框架,开发小程序和APP的推荐框架!

    Thinkphp 6 + Vue 2 + ElementUI + Vxe-table 前后端分离的,一键生成代码和API接口的,通用后台管理系统 快速开发框架,开发小程序和APP的推荐框架! 概述 R ...

  7. 用 Vite+Vue3+Ts 搭建通用后台管理系统

    大厂技术  高级前端  Node进阶 点击上方 程序员成长指北,关注公众号 回复1,加入高级Node交流群 通用后台管理系统整体架构方案(Vue) 项目创建,脚手架的选择(vite or vue-cl ...

  8. 用vite+Vue3+ts搭建通用后台管理系统

    点击上方关注 前端技术江湖,一起学习,天天进步 通用后台管理系统整体架构方案(Vue) 项目创建,脚手架的选择(vite or vue-cli) vue-cli基于webpack封装,生态非常强大,可 ...

  9. 【前端】Vue+Element UI案例:通用后台管理系统-登陆不同用户显示不同菜单、动态添加路由

    文章目录 目标 代码 0.动态地显示菜单:store 1.动态注册路由 2.解决刷新后摆平问题 总代码 本篇修改的代码文件 tab.js 参考视频: VUE项目,VUE项目实战,vue后台管理系统,前 ...

最新文章

  1. 《实施Cisco统一通信管理器(CIPT1)》一2.4 使用分布式呼叫处理的多站点WAN部署模型...
  2. PDF与doc格式互换
  3. prometheus+consul服务发现+alertmanager配置
  4. Css3实现波浪线效果1
  5. [html] 你有使用过webp的图片格式吗?
  6. python语言学完后学什么_学完Python语言可以做什么?发展前景怎么样?
  7. redis笔记_源码_内存分配
  8. pat根据中序遍历和先序遍历_[leetcode/lintcode 题解] 前序遍历和中序遍历树构造二叉树...
  9. MobileNet V3简单总结
  10. Windows 8虚拟机不能全屏的解决方法
  11. 天梯—输出GPLT(C语言)
  12. MATLAB局部放大
  13. 太原理工计算机学科评估,太原理工大学学科评估结果及排名情况怎样
  14. 把tif文件转化成jpg格式报错已解决
  15. 威斯康星麦迪逊计算机专业排名,威斯康星大学麦迪逊分校计算机工程学科排名...
  16. 一张图快速了解23种设计模式
  17. 第九届蓝桥杯大赛软件类国赛
  18. python数据分析的交叉分析和分组分析 -第三次笔记
  19. FPGA电源设计方案
  20. 7 士兵排队---PTA(排序+中位数)(C++)

热门文章

  1. 裸辞4个月,面试了30家公司,终于找到理想工作了
  2. ASPNET MVC项目设置起始页问题修复
  3. 小程序云开发:私家书柜
  4. 今年职高计算机数学高考试题,职高高考试题
  5. 二进制加法 | 循序递进---@二十一画
  6. SQL Server2017配置允许远程连接
  7. Flink难点解析:揭开Watermark的神秘面纱
  8. ​TensorFlow2.0系列教程集合版(附PDF下载)
  9. thinkphp3.2集成phpword,生成word文档并下载
  10. 三大主流框架的优缺点