这篇文章主要总结自己在学习电商后台管理系统课程中遇到的问题及其解决方法,和学到的知识;页面样式之类的就不做整理了
注:很多模块的添加,编辑删除等功能实现都比较相似,在弹窗之前 调用相应的api拿到数据渲染就行了,就不进行整理了
涉及的前端技术栈:
- Vue
- Vue-router
- Element-UI
- Axios
- Echarts
相关技术点:
有些功能模块和页面,要求用户必须登录之后才可以查看,在后面的各个功能模块中,我们需要发送大量的请求来获得数据,再进行页面渲染等操作,那么就需要判断用户的登录状态,登录成功后,才可以拿到相应的数据
很简单,直接使用axios发送请求并对服务器返回的数据进行处理即可
// 挂载路由导航守卫
router.beforeEach((to, from, next) => {
// to代表 将要访问的路径
// from 代表从哪个路径跳转而来
// next 是一个函数表示放行
if (to.path === '/login') return next()
// 获取token
const tokenStr = window.sessionStorage.getItem('token')
if (!tokenStr) return next('/login')
next()
})
通过
:rules
绑定表单验证规则的对象
在表单上通过ref属性绑定之后,通过$refs
拿到对应的表单对象,然后调用validate
方法进行表单验证
// 使用validate方法进行登录前的预校验
this.$refs.loginFormRef.validate(async (valid) => {
if (!valid) return
const { data: res } = await this.$http.post('login', this.loginForm)
if (res.meta.status !== 200) {
return this.$message.error('登陆失败')
}
this.$message.success('登陆成功')
// 1.将登录成功之后的 token 保存到客户端的 sessionStorage 中
// 1.1 项目中除了登录之外的其他API 接口 ,必须在登陆之后才能访问
// 1.2 token 只应该在当前网站打开期间生效 所以将 token保存在 sessionStorage 中
window.sessionStorage.setItem('token', res.data.token)
// 跳转页面到 home
this.$router.push('/home')
由于是基于token实现的登录,所以退出功能,只需要销毁本地的token即可,后续的请求就不会携带token
//清空token
window.sessionStorage.clear()
//跳转到登录页
this.$router.push('/login')
布局方面挺简单的,没遇到什么问题,就不在此整理了
// 设置request拦截器,在发送请求的时候添加token获得权限
axios.interceptors.request.use(config => {
// 展示进度条
NProgress.start()
// 添加token 获得权限
config.headers.Authorization = window.sessionStorage.getItem('token')
return config
})
给菜单添加
router
或者:router="true"
开启路由控制
<el-menu router>
<el-submenu :index="item.id + ''" v-for=“item in menus" :key="item.id">
<template slot="title">
<span>{{item.authName}}span>
template>
<el-menu-item :index="'/' + subItem.path" v-for="subItem in item.children"
:key="subItem.id" >
<span slot="title">{{subItem.authName}}span>
el-menu-item>
el-submenu>
el-menu>
布局使用 ElementUi 就不整理了
scope.row 就是这一行的数据对象
<template slot-scope="scope">
<el-switch v-model="scope.row.mg_state"
@change="stateChanged(scope.row.id, scope.row.mg_state)">
el-switch>
template>
数据分页利用 el-pagination
组件,用用elementUI提供的默认API,例如size-change,current-page等,没什么难点,省略
逻辑都比较简单,也比较相似,省略
例如修改用户:
showEditDialog
函数是在 弹出编辑框之前,通过请求对应api拿到数据渲染
<el-button type="primary" size="mini" icon="el-icon-edit"
@click="showEditDialog(scope.row.id)">el-button>
async showEditDialog(id) {
const { data: res } = await this.$http.get('users/' + id)
if (res.meta.status !== 200) {
return this.$message.error('查询用户信息失败!')
}
// 把获取到的用户信息对象,保存到 编辑表单数据对象中
this.editForm = res.data
this.editDialogVisible = true
}
同样是利用了 作用域插槽
<template slot-scope="scope">
<el-tag size="small" v-if="scope.row.level == 0">一级el-tag>
<el-tag type="success" size="small" v-else-if="scope.row.level == 1">二级el-tag>
<el-tag type="warning" size="small" v-else>三级el-tag>
template>
// 获取权限列表数据
async getRightsList() {
const { data: res } = await this.$http.get('rights/list')
if (res.meta.status !== 200) {
return this.$message.error('获取权限列表失败!')
}
this.rightsList = res.data
}
和前面相似,调用相应api拿到数据即可
<el-row v-for="(item1, i1) in scope.row.children" :key="item1.id" class="centerRow">
<el-col :span="5">
<el-tag closable>{{item1.authName}}el-tag>
<i class="el-icon-caret-right">i>
el-col>
<el-col :span="19">
el-col>
el-row>
<el-row v-for="(item2, i2) in item1.children" :key="item2.id" class="centerRow">
<el-col :span="6">
<el-tag closable type="success">{{item2.authName}}el-tag>
<i class="el-icon-caret-right">i>
el-col>
<el-col :span="18">
<el-tag closable type="warning" v-for="item3 in item2.children" :key="item3.id">
{{item3.authName}}el-tag>
el-col>
el-row>
这一模块引入了一个 第三方树形表格
之前没用过
npm i vue-table-with-tree-grid -S
import Vue from ‘vue’
import ZkTable from ‘vue-table-with-tree-grid’
Vue.use(ZkTable)
<tree-table :data="cateList" :columns="columns" border :selection-type="false"
:expand-type="false" show-index index-text="#" class="tree-table">
<template slot="isok" slot-scope="scope">
<i class="el-icon-success" style="color:#20B2AA;" v-if="scope.row.cat_deleted
=== false">i>
<i class="el-icon-error" style="color:#F92672;" v-else>i>
template>
tree-table>
这一模块数据 分为了 动态参数和静态属性 所以分别发送不同的请求,获得数据保存在本地,再利用tabs组件进行渲染即可,添加,修改,删除功能省略
将字符串形式的数据分隔为数组:
res.data.forEach(item => {
// 把字符串的可选项,分割为数组,重新赋值给 attr_vals
item.attr_vals = item.attr_vals.length > 0 ? item.attr_vals.split(‘,') : []
})
这里用到了一个之前没用过的 el-upload
图片上传组件
基本使用:
<el-upload
action="http://47.96.21.88:8888/api/private/v1/upload"
:headers="uploadHeaders"
:on-preview="handlePreview"
:on-remove="handleRemove"
:on-success="handleSuccess"
list-type="picture">
<el-button size="small" type="primary">点击上传el-button>
el-upload>
通过其内置的方法 on-preview,on-remove等等,可以实现上传图片的预览,删除等功能
这里用了一个第三方的 富文本编辑器
// 安装vue-quill-editor
npm install vue-quill-editor -S
import VueQuillEditor from 'vue-quill-editor‘
Vue.use(VueQuillEditor)
<quill-editor v-model="addForm.goods_introduce">quill-editor>
省略
用到了echarts
// 安装echarts库
npm install echarts -S
// 导入echarts接口
import echarts from ‘echarts’
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(this.$refs.main)
const { data: res } = await this.$http.get('reports/type/1')
if (res.meta.status !== 200) return this.$message.error('初始化折线图失败!')
const data = _.merge(res.data, this.options)
// 绘制图表
myChart.setOption(data)
收获:
- 从刚开始的一头雾水,无从下手,到跟着做一遍后,后面的几个模块比较相似,自己进行了实现
- 最大收获就是从拿到一个项目开始,梳理它的功能模块,然后各个模块再细分为单个功能例如添加,删除,修改等,然后逐个功能进行实现
- 在实现各个功能的时候,从老师那里学到了很多逻辑,包括思考问题的方式,比如这个项目,各个功能要做的大同小异,无非是拿到数据,进行处理,然后渲染,监听用户操作,修改数据,提交请求
- 还有就是之前没有怎么用过的 作用域插槽,出现在项目中,特意又去学了一下,并且了解到新的语法
v-slot
,更加熟练了- 然后就是对于 axios拦截器的使用,比如登录时用到的request,在发起请求时为请求添加token,还有另一个 response,在获得数据时,添加进度条效果;
- 然后就是帮助自己 复习了Vue-router,更加熟悉了路由的操作;
- 对Element-ui的使用更加熟练