后台管理系统

创建项目

一、登录页面

下载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-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
	<el-form-item label="姓名" prop="username">
    	<el-input v-model:"ruleForm.username"></el-input>
    </el-form-item>
</el-form>

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”//一级标题循环遍历 <el-submenu :index="item.id + ''"              v-for="item in menulist"              :key="item.id" >                  //二级标题的v-for循环遍历<el-menu-item :index="subitem.id + ''"                v-for="subitem in item.children"                :key="subitem.id">                    data(){    return {        menulist:[]    }}created(){    this.getMenulist()  //通过生命周期函数,自动执行函数}//通过axios get请求获取数据getMenulist(){    this.$http.get('menus').then(res=>{    console.log(res)}).catch(err=>{    console.log(err)})}

用户管理


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的值就是 获取到的状态值

<template slot-scope="scope">{{scope.row}}</template>

<template slot-scope="scope">            <!-- {{ scope.row }} -->            <el-switch              v-model="scope.row.mg_state"              active-color="#eeb928"              @change="userStateChange(scope.row)"            >            </el-switch>          </template>

操作栏

用到了三个插槽,分别写入三个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标签 将文字 渲染成 标签样式

<!-- 展开列 -->          <el-table-column type="expand">            <template slot-scope="scope">              <el-row v-for="item1 in scope.row.children" :key="item1.id">                <!-- 渲染一级权限 -->                <el-col :span="5">                  <el-tag>{{ item1.authName }}</el-tag>                  <i class="el-icon-caret-right"></i>                </el-col>                <!-- 渲染二级和三级权限 -->                <el-col :span="19">                  <!-- 通过for循环渲染二级权限 -->                  <el-row v-for="secitem in item1.children" :key="secitem.id">                    <!-- 左边渲染二级权限 -->                    <el-col :span="6">                      <el-tag type="success">{{ secitem.authName }}</el-tag>                      <i class="el-icon-caret-right"></i>                    </el-col>                    <!-- 右边渲染三级权限 -->                    <el-col :span="18">                      <el-tag v-for="thitem in secitem.children" :key="thitem.id" >                          {{ thitem.authName }}                      </el-tag>                    </el-col>                  </el-row>                </el-col>              </el-row>            </template>          </el-table-column>

索引列

通过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.功能

  1. 添加分类按钮

给按钮添加点击事件,点击事件触发后,将弹出框的布尔值改为true,

设置弹窗布局,el-from>el-from-item>el-input设置 键值输入框

设置父级分类,el-form-item>el-select

这个选择框的作用就是 选择父级分类之后,获取到最后的父级id的值 以及 自己的等级值

创建 获取父级分类的函数方法,点击按钮之后,调用获取父级分类的方法,得到父级分类列表,

:options 将父级分类列表 动态的添加给参数

选择框里进行选择,通过双向绑定,获取到父级分类的id值,进行判断,如果这个数组里的值的长度大于零时,

说明选择了,然后就将最后一级的父级id值给到数据列表里的id值,然后等级值就是数组的长度值,

点击确定按钮之后,发送post请求,将数据提交,然后通过promise的返回值 确定是否提交成功

  1. 表格布局

用到了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"> 	<tab-pane></tab-pane>	<tab-pane></tab-pane><el-tabs>

弹出框 是共用的 一个弹出框

设置一个函数方法,动态的返回动态属性和静态属性的值,

如果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( )

posted @ 2021-06-24 10:59  larissa404  阅读(210)  评论(0)    收藏  举报