前言

该项目是一款对公司员工及商品管理的后台系统,主要实现功能:公司角色的增删改查,和商品的增删改查,项目的主要模块有,登录,主页,员工管理,权限管理,商品管理,该项目的亮点是权限管理,不同角色登录进入首页,看到的菜单和可操作的按钮是不一样的,如系统管理员可查看和操作所有模块。

1.初始化项目

涉及的前端技术栈:

Vue
Vue是一个用于创建用户界面的开源JavaScript框架
Vue-router
vue-router是Vue官方推出的路由管理器
elementUi
element是基于VUE的一套UI组件库
Axios
Axios,是一个基于promise网络请求库,作用于node.js和浏览器中
Echarts
“ECharts是一款基于JavaScript的数据可视化图表库
Vuex
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库

2.项目功能模块划分

  • 登录/退出功能
  • 主页布局
  • 用户管理模块
  • 权限管理模块
  • 分类管理模块
  • 商品列表模块
  • 订单管理模块
  • 数据统计模块

3.各模块功能实现

3.1封装axios请求

import axios from 'axios'
//因为我们将tokne存入的vuex,所以这里需要引入vuex
import vuex from '../store'var api = axios.create({baseURL: 'http://127.0.0.1:8888/api/private/v1/',timeout: 5000
})api.interceptors.request.use((config) => {if (vuex.state.token) {//这里是进行判断有没有token,如果有token的话通过请求头将token携带过去请求参数config.headers.Authorization = vuex.state.token}return config
})api.interceptors.response.use((res) => {//这里是为了token过期之后是否回退到登陆页面let code = res.data.meta.status//获取返回的状态码if (res.data.meta.msg == "无效token") {//判断返回的msg如果为无效token的话,就说明token过期了,此时弹出一个提示框。MessageBox.confirm('token过期, 是否跳转到登录页面?', '提示', {confirmButtonText: '重新登录',//若用户点击重新登录则回到登录页cancelButtonText: '取消',//若用户点击取消,则留在当前页面,但什么也做不了type: 'warning'}).then(() => {//通过原生js的方法跳转到登录页location.href = '/login'}).catch((err) => {err})}return res.data
})
//最后导出出去
export default api

3.1.1二次封装
这里拿权限的接口为例

// 权限列表
export const menus = () => api.get("/menus")

3.1.2调用
在需要的页面就可以通过.then获取数据

getData() {menus().then((res) => {this.menusList = res.data;});},

3.2登录/退出功能

对于后台管理这个项目来说呢,所有的功能和页面要求用户必须登录之后才可以查看,再后面的各个模块中,需要发送大量请求来获取数据,再进行页面的渲染,那么这个时候就需要进行哦按段用户的登录状态,登录成功后,才可以拿到相应的数据

3.2.1实现登录功能
这个很简单,只需将用户填写的用户名和密码通过接口发送到服务器验证即可,在服务器返回数据后将token存入Vuex

3.2.2
基于elementUi的表单验证

通过:rules绑定表单验证规则的对象,在表单上通过ref绑定,再通过$refs拿到对应的表单对象,然后调用validate方法进行验证

 ruleValidate: {username: [{ required: true, message: "用户名不能为空", trigger: "blur" },{ min: 3, max: 10, message: "用户名长度在3到10个字符",trigger:'blur'},],password: [{ required: true, message: "密码不能为空", trigger: "blur" },{ min: 6, max: 10, message: "用户名长度在6到10个字符",trigger:'blur'},],},

登录校验并将token存入本地

 handleSubmit(name) {let tant = this;this.$refs[name].validate((valid) => {if (valid) {login(this.formValidate).then((res) => {//这里是将token存入vuexthis.$store.commit("token", res.data.token);this.$Notice.success({title: "登录成功",duration: 1,});this.$router.push("/");});} else {this.$Message.error("表单验证失败!");}});},

3.2.3路由守卫控制访问权限

router.beforeEach((to, from, next) => {//to,from,next分别代表要去的地方,从哪里来,和放行或者重定向let token = vuex.state.token//先判断有没有tokenif (token) {//有的话就一路畅通next()} else {//没有的话判断是不是去登录页if (to.path == '/login') {//是的话放行next()} else {//不是的话就强行让他回到登录页next('/login')}}
})

3.2.4退出功能
因为是基于token实现的登录,所以退出只需将存在vuex中的token销毁并跳转到登录页即可

3.3主页布局

这里是使用elementUi的菜单栏组件实现的,只需替换数据即可。
菜单栏的原本数据是树状结构,这里可以在router文件内挨个添加并引入本地路径,但稍显繁琐且代码量增多,那么这里呢就可以使用动态路由模式。

因为我们获取的数据是树状的,所以需要先通过递归获取最下层的结构并处理成列表结构,代码如下


export function fn(data) {//先声明一个空数组,用来存放最终的列表结构let arr = [];//递归函数function deep(data) {//循环每一项data.forEach((item) => {//判断有没有childrenif (item.children.length) {//如果有的话,说明不是底层数据,开始递归deep(item.children);} else {//如果没有的话则证明已经是底层数据了arr.push({//路径名path: "/" + item.path,//name名name: item.authName,//引入,注意   这里的文件还是需要手动配置的component: () => import("@/views/homeList/" + item.path[0].toUpperCase() + item.path.substring(1) + ".vue"),});}});}deep(data);//最终return底层数据的数组return arr;
}

这里是之后的列表数据

最后再使用this.$router.addRoute添加到首页下的children里边就可以了,代码如下

 function loadRoute() {let token = tant.$store.state.token;let menus = JSON.parse(localStorage.getItem("menus"));if (token && menus) {let newList = fn(menus);newList.forEach((item) => {tant.$router.addRoute("Home", item);});}}loadRoute();

3.4用户管理模块

3.4.1

这个用户管理模块,就是由最基本的增删改查来实现的,首先通过接口请求用户列表的数据,然后通过elementUi的table表格渲染就可以了,大部分功能都是操作接口完成的,如根据ID搜索用户,就是传一个id值给后端,后端进行筛选之后返回符合id的用户,我们拿到数据之后进行渲染就可以。还有状态,也是通过接口像后端发送需要修改状态的用户id和修改后的布尔值,即可修改状态。这里值得说一下的有,添加用户和编辑用户可以公用一个模态框,代码如下。

//点击添加将判断的布尔值改为true,点击编辑则改为falsehandleSubmit(name) {//这里根据布尔值判断此次执行函数为编辑还是添加if (this.deilOrAdd) {//如果是添加的话this.$refs[name].validate((valid) => {if (valid) {//通过表单验证this.isShow = false;//通过接口传递参数给后端usersAdd(this.formValidate).then((res) => {if (res.meta.status == 201) {//创建成功后重新获取数据this.getData();this.$Notice.success({title: "创建成功",});}});} else {//表单验证失败this.$Message.error("表单验证失败!");}});} else {//如果为编辑的话let obj = {id: this.userId,obj1: this.formValidate,};//先回填当前编辑用户的数据usersDeil(obj).then((res) => {//通过接口传递参数给后端进行修改if (res.meta.status == 200) {this.$Notice.success({title: "更新成功",});//修改完成重新刷新this.getData();//将模态框隐藏this.isShow = false;}});}},

3.4.2分页
值得一说的还有分页的逻辑了,分页所有的功能都是围绕这currentpagesizetoken来实现的,我这里自己封装了一个分页的组件,代码如下

<template><div class="myPage"><span class="total">共{{ total }}条</span><div class="before"><div @click="sub" class="arrows beforeArrows"></div></div><span@click="item == '...' ? false : $emit('change-current', item)":class="current == item ? 'pageItem pageItemACur' : 'pageItem'"v-for="(item, index) in pagenum":key="index">{{ item }}</span><div class="aftter"><div @click="add" class="arrows aftterArrows"></div></div><p class="toPage">前往<inputclass="inp"type="text"v-model.number="toPage"@keyup.enter="toPageNum"/>页</p></div>
</template>
<script>
export default {name: "demo",props: {//接收父组件传递过来的总条数total: {type: Number,default: 50,},//接收父组件传递过来的每页条数pagesize: {type: Number,default: 5,},//接收父组件传递过来的当前页current: {type: Number,default: 1,},},components: {},data() {return {num: 0,toPage: this.current,};},created() {},computed: {//这里使用计算属性完成pagenum() {//先声明一个存放按钮内容的空数组let pagenumArr = [];//遍历token每页条数就可以获得for (var i = 0; i < Math.ceil(this.total / this.pagesize); i++) {//push到数组pagenumArr.push(i + 1);}//此时需要判断按钮的数量//以这里为例,我希望按钮最大数量为9,所以加了个>9的if判断if (pagenumArr.length > 9) {//再进行判断  当前值是否为5以下if (this.current <= 5) {//为5以下的显示前7个按钮,中间用...代替,最后一个值为数组的长度pagenumArr = [1, 2, 3, 4, 5, 6, 7, "...", pagenumArr.length];} else if (this.current >= pagenumArr[pagenumArr.length - 1] - 4) {//反之判断是否当前值是否是在数组的末尾pagenumArr = [1,"...",pagenumArr.length - 6,pagenumArr.length - 5,pagenumArr.length - 4,pagenumArr.length - 3,pagenumArr.length - 2,pagenumArr.length - 1,pagenumArr.length,];// 如果是在数组的末尾则将1后边的省略为...,最后的值为length--就能得出后边的值} else {//再进行判断是否是在中间点,如果是在中间,则两边以...显示pagenumArr = [1,"...",this.current - 2,this.current - 1,this.current,this.current + 1,this.current + 2,"...",pagenumArr.length,];}}//return出去return pagenumArr;},},methods: {//去第几页的函数toPageNum() {//如果跳转的页码大于总页数,则跳到最后一页if (this.toPage > this.pagenum[this.pagenum.length - 1]) {this.$emit("change-current", this.pagenum[this.pagenum.length - 1]);} else {//反之则跳转到相应页面this.$emit("change-current", this.toPage);}//跳转完input失焦document.querySelector(".inp").blur();},add() {//点击判断是否是最后一位if (this.current >= this.pagenum[this.pagenum.length - 1]) {//是的话returnreturn;} else {//不是则跳转this.$emit("change-current", this.current + 1);}},sub() {//判断是不是第一位if (this.current <= 1) {//是就returnreturn;} else {//不是则跳转this.$emit("change-current", this.current - 1);}},},mounted() {}
};
</script>

3.4.3面包屑导航
我这里的面包屑导航是使用了自己封装的一个函数,代码如下;

 goItem(e) {//在点击路由跳转时触发this.menusList.forEach((item) => {//遍历menusitem.children.forEach((ele) => {//遍历menus里边的每一个childrenif (ele.path == e) {//如果children的path等于路由要跳转的路径的时候this.bread = { Fname: item.authName, Cname: ele.authName };//将data里边的面包屑对象更换,第一个值是父亲的name,第二个值是儿子的name,这样就可以拿这个对象去渲染面包屑了}});});//同时将当前路径存储到data中this.name = e;//进行跳转,这里catch是vue重复调换报错的问题,捕获报错但不发不出来,蛮有趣的。this.$router.push("/" + e).catch((err) => {err;});},
breadShow() {//判断刚刚存入的路径名称this.name = this.name + "";//是不是等于欢迎页if (window.location.hash != "#/welcome") {//是的话不显示面包屑return true;} else {//不是则显示面包屑return false;}},

因为后台管理项目只有两层,所以我这里没用递归,只使用了双层for循环即可完成面包屑效果。

3.4.3还有给用户分配角色
这一步需要在模态框回填该角色的数据,并获取所有角色列表,渲染到下拉菜单里边,选中之后发送请求,携带当前用户id和角色ID就可以给用户分配角色

3.5权限管理模块

权限管理模块,顾名思义,就是给不同的用户分配不同的操作和查阅的权限,而这个权限与用户中间的,又添加了角色这个概念,即给用户分配角色,给角色分配权限,这样会使得进权限分配更加的方便且灵活

3.5.1角色列表


首先需要在点击添加弹出的模态框添加角色,只需填写角色名和角色描述即可通过接口提交就可以了,如图
添加完成之后就可以给这个角色分配相应的权限

我这里也封装了一个tree树状组件,代码如下

 <div class="myTree"><div class="treeP"><b v-if="listFlag" @click="change">{{ isShow ? "-" : "+" }}</b><h4>{{ treeList.label }}</h4></div><div class="treeBox" v-show="isShow"><my-treev-for="(item, index) in treeList.children":key="index":treeList="item"></my-tree></div></div>

这个主要是使用的递归组件的思路,在组件里再使用一次当前的组件,第二次使用组件时就不需要再引入了,然后通过父传子一层一层的向下传递,即可实现递归显示所有树形数据,通过props接收的时候可以定义两种数据类型为Array,Object

props: {treeList: {type: [Object, Array],required: true,},},

而树形组件是否显示呢则是通过计算属性实现的

 listFlag() {return this.treeList.children && this.treeList.children.length;},

判断他是否有children且children有没有长度,这里的返回值就是判断是否隐藏的布尔值。

3.5.2权限列表
这个权限列表只需渲染即可,唯一要注意的点呢就是tag标签通过v-if或者v-show判断以下显示某个颜色的标签即可。

3.6商品管理

3.6.1商品列表
商品列表的增删改查的功能同用户管理的增删改查,都是操作接口即可,而添加商品呢,需要跳转到另外的页面,这里说一下,如果使用的是动态路由的话,那么像welcom欢迎页,还有这个添加商品是需要自己另外配置路由的,因为请求menus列表的时候返回的路径是不包含这两个页面的路径的,所以需要手动配置。
那么现在开始添加商品的操作。
点击添加按钮跳转到添加页,如图所示
这个选择商品分类呢,是一个级联菜单,这里需要将第二级的id通过接口发送给商品添加分类

3.6.2上传图片
然后在商品图片中呢,使用的是elementUi的上传图片的组件。

<el-uploadclass="upload-demo":action="actionUrl":headers="headers":on-preview="handlePreview":on-remove="handleRemove":on-success="handleSuccess"list-type="picture"><el-button size="small" type="primary">点击上传</el-button></el-upload>

:action图片上传的地址
:headers请求头的配置
:on-success上传成功的钩子函数
:on-remove删除的钩子函数
:on-preview——点击列表中已上传的图片的钩子
上传成功后,需要把上传的图片的信息追加到数组中

3.6.3最后还有富文本编辑器

<quill-editor v-model="ruleForm.goods_introduce"> </quill-editor>

3.6.4分类参数
分类参数首先需要选择商品的分类,也是一个级联菜单,选择完之后可以给他们配置参数和属性,也是通过接口进行一些增删改查。

3.6.5商品分类
同用户管理的增删改查,这里不再过多赘述。

3.7数据报表

数据报表我们是使用echarts实现的,echarts的使用方法呢,和elementUi差不多,只需引入之后替换数据即可,需要注意的是呢,这个echarts的模板呢是需要通过ui给的图来选择的。像我刚开始自己学习echarts的时候是哪个好看用哪个,结果跟后台 返回的数据根本对不上,所以写了好久都没写出来,而当我替换了与效果图类似的模板,效果便直接出来了。还有一点,如果你的项目需要打包的话,不建议使用5.0以上的echarts,因为这个版本以上打包时需要在名称前添加* as在打包抽离时不好根据名字去匹配,所以建议使用4.9.0左右的版本。下面是效果

至此,后台管理项目结束。

Vue2+elementUi后台管理项目总结相关推荐

  1. 基于vue2.0 + elementUI 后台管理平台

    Vue-Admin-Demo 这是一个基于vue2.0 + elementUI 后台管理平台 Github: https://github.com/xiahuahua/vue-vux-demo(欢迎S ...

  2. vue考试系统后台管理项目-接口封装调用

    上一篇文章 : vue考试系统后台管理项目-登录.记住密码功能_船长在船上的博客-CSDN博客 考试系统后台管理项目介绍: 技术选型:Vue2.0+Element-ui 项目功能介绍: 账户信息模块: ...

  3. 尚硅谷尚品汇_后台管理项目

    vueProject_尚品汇后台管理 项目源码 文章目录 vueProject_尚品汇后台管理 login/out模块 product模块 login/out模块 .env.development . ...

  4. 电商项目总结java_Vue 电商后台管理项目阶段性总结(推荐)

    一.阶段总结 该项目偏向前端更多一点,后端 API 服务是已经搭建好了的,我们只需要用既可以,(但是作为一个 全栈开发人员,它的数据库的表设计,Restful API 的设计是我们要着重学习的!!!) ...

  5. vue+elementUI 后台管理极简模板

    vue+elementUI 后台管理极简模板 写在前面 此篇文章为一篇说明文档,不是教你从零构建一个后台管理系统,而是基于一个实际项目,已经搭建好了一个后台管理系统的基础框架,教你如何在此基础上快速开 ...

  6. vue考试系统后台管理项目-登录、记住密码功能

    考试系统后台管理项目介绍: 技术选型:Vue2.0+Elemenu-ui 项目功能介绍: 账户信息模块:菜单权限.角色权限设置.角色权限分配.账号设置.公司分组 考试管理模块:新增/编辑/删除考试试题 ...

  7. 从0到1完成一个Vue后台管理项目(九、引入Breadcrumb面包屑,更改bug)

    往期 从0到1完成一个Vue后台管理项目(一.创建项目) 从0到1完成一个Vue后台管理项目(二.使用element-ui) 从0到1完成一个Vue后台管理项目(三.使用SCSS/LESS,安装图标库 ...

  8. SSM 电影后台管理项目

    SSM 电影后台管理项目 概述 通过对数据库中一张表的CRUD,将相应的操作结果渲染到页面上. 笔者通过这篇博客还原了项目(当然有一些隐藏的坑),然后将该项目上传到了Github.Gitee,在末尾会 ...

  9. elementui后台管理demo

    elementui后台管理demo 第一次尝试做后台管理的框架,做的时候也有想过用别的demo,后来想一想还是算了,虽然网上很多,但是还是自己写出来的有意义,虽然有很多不足,但是是自己写的,自己知根知 ...

最新文章

  1. 教育部免费开放的2.4万门网课,都在这里!
  2. 使用SQLCMD在SQLServer执行多个脚本
  3. 2.监控软件zabbix-客户端安装
  4. 深入浅出深度学习(三)线性代数基础
  5. 中文版php.ini
  6. split函数python统计英文单词_统计一篇英文文章单词个数,取出出现频次前10的单词(Python实现)...
  7. python opencv 录制视频_python - 使用Opencv Python多线程录制视频 - 堆栈内存溢出
  8. JS:ES6-8 Promise入门
  9. PHP $_SERVER['PHP_SELF']、$_SERVER['SCRIPT_NAME'] 与 $_SERVER['REQUEST_URI'] 之间的区别
  10. 使用 java -jar命令启动jar包时报不支持的jdk版本异常
  11. 灭蚊灯UKCA FCC GB4706安全检测认证
  12. crout分解计算例题_吃透高考数学17个必考题型,基础再差也能考130!(内附解题技巧+例题解析)...
  13. 60个英文阅读网站强力推荐
  14. 柱状图中最大的矩形多种解法
  15. kernel panic分析
  16. egret白鹭引擎基础介绍
  17. k8s与日志--journalbeat源码解读 1
  18. 利用bind方便多域应用的开发
  19. visio绘制叠色图
  20. QT编程从入门到精通之十一:“第三章:Qt Creator”之“3.5 构建与运行程序”

热门文章

  1. 鲸会务为活动现场提供数字化升级方案
  2. 计算机基础与应用相关的论文,计算机基础方面论文范文资料,与国内高校计算机基础教育相关毕业论文模板范文...
  3. ESP32设备驱动-MAX30100心率监测传感器驱动
  4. Android模仿软键盘实现软键盘的删除功能(逐个删除EditText的输入元素)
  5. 【托业】【新托业全真模拟】疑难语法题知识点总结(01~05)
  6. ViveInputUtility-按键映射与获取(2)
  7. Oracle数据库管理员认证三大认证的区别和意义
  8. 基于虹软使用Java实现人脸识别、人脸比对、活性检测等
  9. Freemarker 宏
  10. 爬壁除锈机器人_除锈爬壁机器人控制系统的设计