后台管理系统
创建项目
一、登录页面
下载element-ui插件,引入element-ui
npm i element-ui -S
下载less less-loader
npm install less less-loader --save-dev
设置base.css设置全局样式,然后引入到main.js中,
设置登录框,用到了position:absolute,绝对定位以及transfrom设置登录框居中
利用element-ui 的el-from组件
<el-input v-model:"ruleForm.username">
export default{
data(){
ruleForm:{
username:"",
password:""
}
}
}
通过v-model双向绑定,获取用户输入的姓名和密码,
给登录按钮添加点击点击事件,点击事件触发后,通过validate方法检验输入是否合法,合法的话,通过axios访问接口,
//在main.js中引入axios
import axios from 'axios'
Vue.prototype.$http = axios
axios.defaults.baseURL = '接口地址'
//使用axios发送 post请求
this.$http({
methods:'post',
url:'login',
data:{
username:username;
password:password
}
}).then(res=>{
consle.log(res)
}).catch(err=>{
console.log(err)
})
res中的信息,data中有一个status参数,就是状态码,登录成功的话为200
如果状态码不是200,则返回登录失败的信息
这里用到了element-ui中的message提示方法
如果登录成功的话,就获取res中的data里的token值,将token保存到本地,并且路由跳转到首页
this.$message.success('登录成功');
window.sessionStorage.setItem("token",res.data.token)
this.$router.push('/home')
路由导航守卫控制访问权限
通过用户想要访问的地址 以及手里是否拿着token 来决定用户具体决定访问哪个界面
如果用户没有登录,但是直接通过URL访问特定页面,需要重新导航到登录页面
beforeEach
前置钩子函数,在路由跳转之前进行回调,将url改掉
router.beforeEach((to,from,next)=>{
})
to:要去的地址
from:从哪来的地址
next:放行
导航守卫
router.beforeEach((to,from,next)=>{
if(to.path === '/login') {
return next() //如果要访问的页面就是登录页,直接放行
}
const tokenStr = window.sessionStorage.getItem('token')
if(!tokenStr){
return next('/login') 如果传过来token为空,则取反为true,满足条件,强制跳转到登录页面
}
next()
})
登录退出
销毁本地的token
//清空token
window.sessionStorge.clear()
//跳转到登录页面
this.$router.push('/login')
请求拦截
axios.interceptors.request.use(config => {
console.log(config);
config.headers.Authorization = window.sessionStorage.getItem("token");
return config;
});
学到的一个小点
想要改变element-ui el-input 组件获得焦点后边框样式的高亮颜色
用到了input的deep深穿透
input的 父级class /deep/ .el-input__inner:focus{ border-color:red}
border-sizing
二、主页面
首先是总体布局,用了element-ui的lContainer 布局容器
侧边栏容器就是放tabbar导航栏,用了NavMenu 导航菜单组件
分为以及标题和二级标题
然后一级标题的具体内容通过v-for循环遍历接口中的数据进行渲染
根据二级标题,建立各个组件的页面,并添加到路由中,
实现二级标题和路由的绑定 是通过element-ui提供了 router属性,给二级标题添加了router属性的话,点击二级标题,url就跳到了对应的路径
/v-for=“item in menulist”//一级标题循环遍历
用户管理
1.用户列表

用户列表界面
1.布局
头部用到面包屑布局
中间用到卡片布局
卡片布局中头部是 一个搜索框 和一个按钮
中间是一个table表格
尾部是一个分页组件
2.功能实现
搜索功能
clear 在点击由 clearable 属性生成的清空按钮时触发
clearable 是否可清空
clearable就是后面多了一个小 × 号

clear 动态绑定 获取用户列表方法,就是实现在清空之后 列表回到之前的样子
添加用户
给添加用户按钮添加 点击事件,点击事件触发后 弹出添加用户框
添加dialog组件,布尔值首先设置为false,点击事件触发后,将false 改为true
中间的部分 运用 “From表单”进行布局
调用接口发送 post请求,将表单中的数据 当做post请求的data数据,发送请求,然后通过promise的返回值判断res中的信息,如果status为200那么就是添加成功

用户列表
首先用到table组件进行布局,
然后创建 获取用户列表的事件,通过axios发送get请求,获取到res.data
并在生命周期函数created( )中调用,一经创建就渲染列表
如何将true和false的布尔值 装换成状态按钮
用到template 的插槽,然后用到switch开关组件,
v-model的值就是 获取到的状态值
{{scope.row}}
<el-switch v-model="scope.row.mg_state" active-color="#eeb928" @change="userStateChange(scope.row)" >
操作栏
用到了三个插槽,分别写入三个button按钮

第一个为编辑按钮
点击之后,弹出修改对话框,中间布局用到from表单,然后添加点击事件,点击之后发送get请求,通过id获取到当前ida对应的用户数据,并渲染到界面
取消按钮点击之后,就将修改对话框的布尔值改为false,
点击确定按钮之后,要发送put请求,调用接口,返回promise的返回值,判断修改成功还是失败

删除按钮
弹出提示框 提醒是否真正删除

给取消按钮添加 事件,点击取消后,返回信息 “取消成功”
点击确定按钮之后,发送delete请求,通过返回值判断是否删除成功
分配角色

权限管理
2.权限管理

1.布局
头部面包屑
中间 卡片 布局
用到table组件进行布局
2.功能实现
创建 获取权限列表的事件,并添加到生命周期函数created()中,一经创建便渲染到页面上,
然后权限等级列表
通过template插槽,添加button按钮,然后通过v-if , v-else-if, v-else 分别对应获取到了权限的0 1 2的数值,
然后给按钮添加不同的type类型,然后实现等级按钮的出现

权限管理 用户管理 角色管理 三者关系
用户绑定了不同的角色,把权限分配各不同的角色
3.角色列表


1.布局
添加角色按钮
卡片组件布局
(列表分为 展开列 和索引列)
展开列布局:
设置el-row 标签 包含两个el-col标签,分别存放一级权限 和二三级权限

二三级权限的布局

定义el-row标签,存放两个el-col标签,用来存放二级权限列表和三级权限列表
通过v-for 循环遍历 item1.children,渲染到界面,
二级权限每行的值 就是 item2.authName,
三级权限 就在el-tag中 利用v-vor循环 item2.children ,渲染出 item3.authName的值
2.功能实现
展开列
通过设置 type="expand" 和 Scoped slot 可以开启展开行功能,el-table-column 的模板会被渲染成为展开行的内容,展开行可访问的属性与使用自定义列模板时的 Scoped slot 相同。
展开列就是利用 el-table组件 类型值设置为expand, 就是展开列,然后加入template插槽,插槽里有三级菜单,所以进行三次渲染
设置el-row标签 通过v-for循环遍历 scope.row.children ,渲染一级菜单,
然后设置el-col行标签,每一行的值都是 scope.row.children 的每一项的authName
通过el-tag标签 将文字 渲染成 标签样式
索引列
通过table组件设置布局,调用接口发送get请求,将数据渲染到页面
设置getroledata函数方法,并添加到生命周期函数中,当访问界面,就请求数据渲染到页面上
添加角色
给按钮添加click点击事件,点击之后弹出dialog的弹出框,将弹出框的布尔值改为true,
然后给确定按钮添加点击事件,
并在方法中发送post请求,data的值就为,设置的表单数据,
根据promise的返回值判断是否成功添加
操作

编辑按钮和操作按钮就是针对这个表格,编辑这一行的数据 或者删除这一行的数据,跟其他无关
编辑按钮,删除按钮,分配权限按钮 都是添加在插槽里的
然后按钮的点击事件都是在插槽里的,
并且能通过插槽的scope 获取到整行的数据scop.row
之后 通过传过来的id进行一些操作
编辑按钮

编辑按钮添加点击事件,点击之后 弹出框的布尔值变为true
并通过接口发送get请求,通过传过来的scope.row.id 作为id值进行数据的调用
修改数据之后,给确定按钮添加事件,发送post请求,通过promise的返回值判断是否修改成功
调用接口数据是在
删除按钮

删除按钮,添加点击事件,点击删除按钮之后,弹出提示框,点击取消的话值为config,确定的话值为confirm,
如果是confirm 就发送delete请求,将数据删除,通过promise返回值判断是否删除成功
给取消添加取消成功的提示,就是当值为config时,返回,this.$message.info('取消成功')
分配权限按钮

弹出框用了el-tree布局
点击分配权限按钮,将弹框的布尔值改为true,
并发送get请求,获取数据列表,
给确定按钮添加点击事件,
//将所有被选中的小标签和半个的小标签都获取到 组成一个新的数组
//将数组改成 以逗号拼接的字符串
const idStr = keys.join(",");
发送post 请求,然后通过promise的返回值判断添加成功或失败
商品管理
4.商品分类



1.布局
面包屑导航条
添加分类的按钮,有父级分类的选择框
然后卡片布局
一个树形表格,将分类级别展示出来
然后 分页组件
2.功能
- 添加分类按钮
给按钮添加点击事件,点击事件触发后,将弹出框的布尔值改为true,
设置弹窗布局,el-from>el-from-item>el-input设置 键值输入框
设置父级分类,el-form-item>el-select
这个选择框的作用就是 选择父级分类之后,获取到最后的父级id的值 以及 自己的等级值
创建 获取父级分类的函数方法,点击按钮之后,调用获取父级分类的方法,得到父级分类列表,
:options 将父级分类列表 动态的添加给参数
选择框里进行选择,通过双向绑定,获取到父级分类的id值,进行判断,如果这个数组里的值的长度大于零时,
说明选择了,然后就将最后一级的父级id值给到数据列表里的id值,然后等级值就是数组的长度值,
点击确定按钮之后,发送post请求,将数据提交,然后通过promise的返回值 确定是否提交成功
- 表格布局
用到了tree-table布局,然后里面的每一列 都通过 columns定义,定义了type=template 之后,通过template标签
定义具体的列
一级 二级 三级 等级列
通过el-tag标签定义 一级二级三级的标签,然后通过v-if v-else-if v-else 来决定哪个标签显示
5.商品列表



时间的转换 用到了filter 过滤器
Vue.filter("dataFormat", function(originVal) { const dt = new Date(originVal); const y = dt.getFullYear(); const m = (dt.getMonth() + 1 + "").padStart(2, "0"); const d = (dt.getDate() + "").padStart(2, "0"); const hh = (dt.getHours() + "").padStart(2, "0"); const mm = (dt.getMinutes() + "").padStart(2, "0"); const ss = (dt.getSeconds() + "").padStart(2, "0"); return ${y}-${m}-${d}-${hh}:${mm}:${ss};});
6.分类参数




用到tabs标签,v-model 双向绑定了活跃事件,给两个面板起了名字,谁获取 取到谁的值,
动态设置为many 静态设置为only
<el-tabs v-model=“activename” @click="tabsclick">
弹出框 是共用的 一个弹出框
设置一个函数方法,动态的返回动态属性和静态属性的值,
如果activename当前等于many 那么返回动态属性 否则返回静态属性
就实现了动态获取标题的值
展开列的功能实现
定义一个template组件,然后定义el-tag 标签,并通过v-for 循环遍历本行的 标签值
这里需要补充说明的一点是 标签数据需要经过一些处理
从接口中调用出的数据 是 一个字符串形式
通过forEach 循环遍历 每一项 ,通过spilt添加空格 进行分割
它的返回值为一个数组
就实现了 字符串转换为数组
然后 设置v-tag标签,通过 v-for循环遍历数组 展示到标签列
这里用到的是forEach,没用map ,forEach 是在原来的基础上进行改变,map是产生一个新的数组
这里不能用新的数组,是因为在循环遍历标签的时候,是遍历获取到的数据列表里的值,map的话是产生了一个新的数组,无法进行调用
数据报表

怎么实现数据报表呢
下载Echart 插件,第一步引入echart
第二步,在卡片区域定义一个div 就是dom渲染的区域
第三步,在mounted函数中 基于准备好的dom,初始化echarts实例
初始化图标 必须要在dom元素都渲染完毕之后
第四步 // 指定图表的配置项和数据 (或发送请求获取数据)
第五步 // 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
优化
1.通过nprogress 添加进度条
下载插件,在main.js中引用,在axios拦截之前 nprogress.start( ) 在响应请求时nprogress.done( )

浙公网安备 33010602011771号