大家好,又见面了,我是你们的朋友全栈君。
vue电商后台管理系统-阶段总结
上个月把这个项目做完简单整理了一下文档,和大家交流分享一下
一、项目技术栈
前端
-
前端采用 vue cli 脚手架搭建框架,使用 element UI 美化项目结构
-
环境依赖(开发依赖,运行依赖)
- 富文本编辑器
- nprogress加载进度条
- echarts图表展示
- 第三方http库 axios
后端
后端是已经写好了的,采用 express 搭建的 API 服务,返回的数据是 JSON 格式的数据,只需要导入数据库,并配置一下数据库信息,就可以跑起来了,也有对应的api文档
数据库
数据库采用 MySQL 5.7存储,我们只需要将项目的 sql 文件导入即可
二、开发流程
1.项目初始化
项目初始化
- 打开cmd运行vue ui
- 选择工作目录创建项目文件夹
- 安装element ui插件选择按需加载(如果添加全部会导致文件的体积过大)
- 安装axios依赖以发起Ajax请求
- 初始化git仓库
2.后台配置
- 把数据库的文件导入mysql的数据库中
- powershell运行node .\app.js 启动后台的api接口
3.登录以及退出
登录的业务流程
- 在登录页面输入用户名和密码
- 调用后台接口进行验证
- 通过验证后,根据后台的响应状态跳转到项目主页
登录业务的相关技术点
- 通过cookie在客户端记录状态
- 通过session在服务器端记录状态
- 通过token方式维持状态
token原理分析
登陆页面的布局
用到了以下的elment ui组件
- el-form
- el-form-item
- el-input
- el-button
- 字体图标
创建登陆组件
在components文件夹中新建Login.vue组件
template,script,style标签,style标签中的scoped可以防止组件之间的样式冲突
<template>
<div>
<!-- 头像 -->
<!-- 登录区域 -->
</div>
</template>
<script> export default {
data() {
return {
} } } </script>
<style lang="less" scoped> </style>
配置less、less-loader依赖
退出
- 清空token
- 跳转到登录页
// 给退出的按钮绑定一个logout事件
logout() {
// 清空token
window.sessionStorage.clear()
// 跳转到登录页
this.$router.push('/login')
},
3.主页面布局、用户列表功能
主页面布局
- 结构布局采用了element ui里的container组件
侧边栏的布局以及渲染 请求数据
在element-ui中也提供了相应的组件,在NavMenu导航菜单中可以找到相应的组件对应的区域
data中定义一个数组menulist来接收左侧菜单数据
// 获取所有菜单
async getMenuList() {
const {
data: res} = await this.$http.get('menus')
if (res.meta.status !== 200) return this.this.$message.error(res.meta.msg)
this.menulist = res.data
console.log(res);
},
侧边栏菜单的伸缩
定义isCollapse属性默认false,点击切换状态
el-aside :width="isCollapse ? '64px' : '200px'">
<div class="toggle-button" @click="toggleCollapsse">?</div>
// 点击按钮 切换菜单的折叠与展开
toggleCollapsse() {
this.isCollapse = !this.isCollapse
},
用户列表功能
用到了以下element ui组件,记得按需导入在element.js中注册
- BreadCRUMB面包屑导航
- Card卡片视图
- Form表单
- Table表格
- DIalog对话框
- Pagination分页
- Tooltip文字提示- Switch开关
- MessageBox
element ui 按需导入
面包屑导航区域
<!-- 面包屑导航 -->
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
<el-breadcrumb-item>用户管理</el-breadcrumb-item>
<el-breadcrumb-item>用户列表</el-breadcrumb-item>
</el-breadcrumb>
卡片视图区域、搜索框、添加按钮
<!-- 卡片试图区域 -->
<el-card>
<!-- 搜索与添加 -->
<el-row :gutter="20">
<el-col :span="8">
<el-input placeholder="请输入内容" v-model="queryInfo.query" clearable @clear="getUserList"
>
<el-button slot="append" icon="el-icon-search" @click="getUserList" ></el-button>
</el-input>
</el-col>
<!-- 按钮 -->
<el-col :span="4">
<el-button type="primary" @click="addDialogVisible = true"
>添加用户</el-button
>
</el-col>
</el-row>
</el-card>
搜索功能的实现
将值利用绑定到queryInfo.query
// 获取用户列表的参数对象
queryInfo: {
query: '',
// 当前的页数
pagenum: 1,
// 当前每页显示多少条数据
pagesize: 2,
},
获取用户列表数据
<script>
export default {
data() {
return {
//获取查询用户信息的参数
queryInfo: {
query: '',
pagenum: 1,
pagesize: 2
},
//保存请求回来的用户列表数据
userList:[],
total:0
}
},
created() {
this.getUserList()
},
methods: {
async getUserList() {
//发送请求获取用户列表数据
const {
res: data } = await this.$http.get('users', {
params: this.queryInfo
})
//如果返回状态为异常状态则报错并返回
if (res.meta.status !== 200)
return this.$message.error('获取用户列表失败')
//如果返回状态正常,将请求的数据保存在data中
this.userList = res.data.users;
this.total = res.data.total;
}
}
}
</script>
分页
- element.js中导入组件Pagination
- 更改组件中的绑定数据
@size-change:监听pagesize改变的事件
@current-change:监听页码值改变的事件
:current-page:当前页
:page-sizes:一页的的信息条数
:page-size:当前的页数
layout:控制显示内容
:total:总共的信息条数
- 代码
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="queryInfo.pagenum"
:page-sizes="[1, 2, 5, 10]"
:page-size="queryInfo.pagesize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
>
</el-pagination>
修改用户状态
swich开关
发送put请求时携带一个用户id和用户状态,请求失败将按钮重置并提示报错,请求成功消息提示
// 监听switch开关状态的变化
async userStateChanged(userinfo) {
const {
data: res } = await this.$http.put(
`users/${
userinfo.id}/state/${
userinfo.mg_state}`
)
if (res.meta.status !== 200) {
userinfo.mg_state = !userinfo.mg_state
return this.$message.error('更新用户状态失败!')
}
this.$message.success('更新用户状态成功!')
},
4.权限管理模块
权限列表
使用三重嵌套for循环生成权限下拉列表
<el-table-column type="expand">
<template slot-scope="scope">
<el-row :class="['bdbottom',i1===0?'bdtop':'','vcenter']" v-for="(item1,i1) in scope.row.children" :key="item1.id">
<!-- 渲染一级权限 -->
<el-col :span="5">
<el-tag closable @close="removeRightById(scope.row,item1.id)">{
{
item1.authName}}</el-tag>
<i class="el-icon-caret-right"></i>
</el-col>
<!-- 渲染二级和三级权限 -->
<el-col :span="19">
<el-row :class="[i2===0?'':'bdtop','vcenter']" v-for="(item2,i2) in item1.children" :key="item2.id">
<el-col :span="6">
<el-tag type="success" closable @close="removeRightById(scope.row,item2.id)">{
{
item2.authName}}</el-tag>
<i class="el-icon-caret-right"></i>
</el-col>
<el-col :span="18">
<el-tag type="warning" v-for="item3 in item2.children" :key="item3.id" closable @close="removeRightById(scope.row,item3.id)">{
{
item3.authName}}</el-tag>
</el-col>
</el-row>
</el-col>
</el-row>
</template>
</el-table-column>
角色列表
-
新建组件,创建路由
-
面包屑导航
-
卡片视图
-
在data中添加一个rightsList数据,在methods中提供一个getRightsList方法发送请求获取权限列表数据,在created中调用这个方法获取数据,同时在页面上写出卡片的视图区域
-
export default { data(){ return { roleList:[] } },created(){ this.getRoleList(); },methods:{ async getRoleList(){ const { data:res} = await this.$http.get('roles') //如果返回状态为异常状态则报错并返回 // if (res.meta.status !== 200) // return this.$message.error('获取角色列表失败') // //如果返回状态正常,将请求的数据保存在data中 // this.roleList = res.data console.log(res.data) this.roleList = res.data; } }
- 卡片视图的区域
<!-- 卡片视图区 --> <el-card> <!-- 添加角色按钮区 --> <el-row> <el-col> <el-button type="primary" @click="addDialogVisible=true">添加角色</el-button> </el-col> </el-row> <!-- 角色列表区 --> <!-- row-key="id" 是2019年3月提供的新特性, if there's nested data, rowKey is required. 如果这是一个嵌套的数据,rowkey 是必须添加的属性 --> <el-table row-key="id" :data="roleList" border stripe> <el-table-column type="expand"> </el-table-column> <el-table-column label="#" type="index"></el-table-column> <el-table-column label="角色名称" prop="roleName"></el-table-column> <el-table-column label="角色描述" prop="roleDesc"></el-table-column> <el-table-column label="操作"> <template slot-scope="scope" width="300px"> <el-button size="mini" type="primary" icon="el-icon-edit" @click="showEditDialog(scope.row.id)">编辑</el-button> <el-button size="mini" type="danger" icon="el-icon-delete" @click="removeRoleById(scope.row.id)">删除</el-button> <el-button size="mini" type="warning" icon="el-icon-setting" @click="showSetRightDialog(scope.row)">分配权限</el-button> </template> </el-table-column> </el-table> </el-card>
-
权限删除功能
给每一个权限的el-tag添加closable属性,是的权限右侧出现“X”图标
再给el-tag添加绑定close事件处理函数removeRightById(scope.row,item1.id)
removeRightById(scope.row,item2.id)
removeRightById(scope.row,item3.id)
//根据Id删除对应的权限
async removeRightById(role,rightId){
//弹框提示用户是否删除
const confirmRes=await this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
//如果用户点击确认,则confirmResult 为'confirm'
//如果用户点击取消, 则confirmResult获取的就是catch的错误消息'cancel'
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).catch(err => err)
if(confirmRes!=='confirm'){
return this.$message.info('取消了删除!')
}
//用户点击了确定表示真的要删除
//当发送delete请求之后,返回的数据就是最新的角色权限信息
const {
data:res}=await this.$http.delete(`roles/${
role.id}/rights/${
rightId}`)
if(res.meta.status!==200){
return this.$message.error('删除权限失败!')
}
//无需再重新加载所有权限
//只需要对现有的角色权限进行更新即可
role.children=res.data
this.$message.success('删除权限成功!')
}
5.商品管理模块
商品分类
懒得写了,拜拜家人们
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/131525.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...