后台管理
一、使用vue4.x脚手架创建一个空的项目
二、分析后台管理功能需求
- 登录
- 后台用户管理
- 权限管理 - 角色列表:用户的角色 - 权限列表:每个角色对应的权限,能干什么事情
- 商品管理 - 商品列表 - 分类参数 - 商品分类
- 订单管理
- 数据统计
三、测试接口
使用postman或apipost测试接口
-
跨域:
1.CORS 跨域
2.代理(前端代理(利用webpack中的proxy),后端代理:nginx反向代理)
3.jsonp(pc传统的老项目,jquery,js可能还会用)
-
接口规范:rest full API 设计规范,用于 Web 数据接口的设计
提交方式:动词
- GET:读取(Read)
- POST:新建(Create)
- PUT:更新(Update)
- PATCH:更新(Update),通常是部分更新
- DELETE:删除(Delete)
例如:
获取:GET /users/1001 获取所有用户
创建:POST /users {id:1001,name:'jack',age:20} 创建一个 {id:1001,name:'allice'} 用户
全部更新PUT /user {id:1001,name:'jack'} 更新一个 id为1001的 用户为jack
部分更新 PATCH /user {id:1001,name:'jack'} 更新一个 id为1001的 用户为jack
删除 DELETE /user/1001 代表删除id为1001的用户
请求成功返回状态码:
GET: 200 OK
POST: 201 Created
PUT: 200 OK
PATCH: 200 OK
DELETE: 204 No Content 有的返回200
登录:
添加用户:
{
"data": {
"id": 3407,
"username": "jack888",
"mobile": "13581234567",
"email": "jack888@126.com",
"role_id": -1,
"create_time": 1591599027
},
"meta": {
"msg": "创建成功",
"status": 201
}
}
四、技术栈:Vue+Element UI+Vue-router-Vuex+sass
-
安装Element UI
npm i element-ui
-
在main.js中引入element-ui
- 完整引入
import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; Vue.use(ElementUI);
-
按需引入
1.首先,安装 babel-plugin-component: npm install babel-plugin-component -D 2.配置.babelrc { "presets": [["es2015", { "modules": false }]], "plugins": [ [ "component", { "libraryName": "element-ui", "styleLibraryName": "theme-chalk" } ] ] } 3.使用相关组件 import { Button, Select } from 'element-ui';
-
用Element UI实现布局
-
登录
- el-form>el-form-item>el-input
- 样式调整
- 功能: - 表单验证 - 登录:成功跳转到首页并给出成功提示,失败给出失败的提示 - el-form属性
:model="ruleForm" 表单的数据源 :rules="rules" 表单的验证规则 prop:代表要验证的字段 <el-form-item label="帐号" prop="username"> <el-input v-model="ruleForm.username" type="text"></el-input> </el-form-item> 通过给表单登录按钮el-button添加方法实现验证和登录: goLogin() { this.$refs["login_Form"].validate(valid => { //表单通过validate方法实现整体表单难,其中valid为true代表所有验证规则通过,否则报错 if (valid) { //向后台提交用户信息 axios this.$http .post( "https://www.liulongbin.top:8888/api/private/v1/login", this.ruleForm ) .then(result => { console.log("登录成功返回的数据:", result); //解构赋值 const { data: res, meta: { msg, status } } = result.data; const { token } = res; if (status === 200) { //1.存token cookie,localStorage,sessionStorage localStorage.setItem("token", token); //二次封装 set() get(),remove() //2.跳转到后台首页 this.$router.push({ name: "Home" }); //3.登录成功提示 this.$message({ message: "登录成功", type: "success" }); } else if(status===400) { console.log(222222) //登录失败提示 this.$message({ message: msg, type: "error" }); } }) .catch(error => { console.log("error:", error); //登录失败提示 this.$message({ message: "登录失败", type: "error" }); }); } else { //登录失败,给出失败的提示 return false; } }); }
-
一、首页布局容器
<el-container>:外层容器
<el-header>:顶栏容器。
<el-aside>:侧边栏容器。
<el-main>:主要区域容器。
<el-footer>:底栏容器。
如果给style加上scoped之后样式穿透,
scoped:组件的局部样式,不会污染全局
如果出现在scoped局部样式中修改ui框架的样式,例如:Element ui,iview,vant ui,可能不生效,则需要用下面的两个符号处理,主要看vue-loader官方文档
参考:https://vue-loader.vuejs.org/zh/guide/scoped-css.html#%E5%AD%90%E7%BB%84%E4%BB%B6%E7%9A%84%E6%A0%B9%E5%85%83%E7%B4%A0
>>>
/deep/
Vue Loader 特性:
允许为 Vue 组件的每个部分使用其它的 webpack loader,例如在 <style> 的部分使用 Sass 和在 <template> 的部分使用 Pug;
允许在一个 .vue 文件中使用自定义块,并对其运用自定义的 loader 链;
使用 webpack loader 将 <style> 和 <template> 中引用的资源当作模块依赖来处理;
为每个组件模拟出 scoped CSS;
在开发过程中使用热重载来保持状态。
二、Layout布局
- el-row行
- el-col列
最多24列
例如:
<el-row>
<el-col :span="3">
<div class="grid-content bg-purple">公司名称-Logo </div>
</el-col>
<el-col :span="18">
<div class="grid-content bg-purple-light">后台管理系统</div>
</el-col>
<el-col :span="3">
<div class="grid-content bg-purple">
<button>退出</button>
</div>
</el-col>
三、导航菜单
- 导航菜单的基本使用
el-menu > el-submenu > el-menu-item
el-submenu index保持子菜单索引唯一,否是会有冲突
unique-opened:是否只保持一个子菜单的展开
- 给导航菜单添加路由模式
<el-menu :router="true"> </el-menu>
<el-menu-item index="home"> //其中index中的值为路由添加中的path
<i class="el-icon-s-grid"></i>
<span>用户列表</span>
</el-menu-item>
- 添加面包屑导航
el-breadcrumb > el-breadcrumb-item
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
<el-breadcrumb-item>用户管理</el-breadcrumb-item>
<el-breadcrumb-item>用户列表</el-breadcrumb-item>
</el-breadcrumb>
- 添加搜索框和添加用户按钮
<el-input placeholder="请输入内容" v-model="query" class="searchInput">
<el-button slot="append" icon="el-icon-search"></el-button>
</el-input>
- 添加表格和分页
el-table > el-table-column
el-table:整个表格 通过注入data属性添加数据源
el-table-column:表格列 通过添加prop指定渲染哪个属性的值
例如:
<el-table :data="tableData" class="user_table" border style="width: 100%">
<el-table-column type="index" label="#" width="40"></el-table-column>
<el-table-column prop="date" label="姓名" width="180"></el-table-column>
<el-table-column prop="address" label="邮箱"></el-table-column>
<el-table-column prop="address" label="电话"></el-table-column>
<el-table-column prop="address" label="角色"></el-table-column>
<el-table-column prop="address" label="状态"></el-table-column>
<el-table-column prop="address" label="操作"></el-table-column>
</el-table>
表格数据渲染
- 使用get请求获取用户列表
- 流程 获取token->配置请求头->发起数据请求
1.const token=localStorage.getItem('token');
2.配置头信息,在封装的request请求中去写
this.$http.defaults.headers['Authorization']=token
3.this.$http({
method:'get',
url:'/users',
params:this.pageinfo
})
axios通过params来向后台传递参数
如果是post请求:
this.$http({
method:'post',
url:'/users',
data:this.pageinfo
})
-
对后台返回的数据格式进行二次处理,比如注册时间
后台返回的数据格式不是咱们想要的,在vue中如何处理
vue的过滤器来处理的:例如:货币$,千分分隔符,性别0,1咱们要处理男,女
Vue.filter()
filters:{}
//创建一个日期的全局过滤器 //Vue.filter('过滤器名',函数) Vue.filter('date', function (t) { return moment(t).format("YYYY-MM-DD h:mm:ss a") })
处理日期插件:moment
npm i moment moment.locale('zh-cn') //设置中文 moment(t).format("YYYY-MM-DD h:mm:ss a") 说明:t代表要传递的时间戳 例如:"create_time": 1486720211,
-
如果对表格数据进行内部处理再输出,通过在el-table-column中内嵌template,通过slot-scope来指定数据源
<template slot-scope="scope"> <span >{{ scope.row.create_time | date }}</span> </template>
-
分页
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="pageinfo.pagenum" :page-sizes="[100, 200, 300, 400]" :page-size="100" layout="total, sizes, prev, pager, next, jumper" :total="400" ></el-pagination> 说明: 1.@size-change:代表pageSize 改变时会触发 2.@current-change:代表当前页码改变时触发 3.current-page:表示当前页码 4.page-sizes:每页显示n条数据的数组 [2,5,10,15] 5.page-size:默认的每页条数 6. layout:分页的整体布局 例如:"total, sizes, prev, pager, next, jumper
一、搜索和添加用户
- 搜索实现思路
-
获取输入框的值(也称关键字)模糊搜索,精确搜索
-
通过事件触发将获取的值通过ajax请求搜索接口传递给后台
-
后台服务器通过服务端语言(node,PHP,Java)实现接收浏览器请求
-
后端语言查询数据库(Mysql,mongodb)
-
将查询的结果根据搜索接口约定好的json格式返回给浏览器
-
通过前端JS将返回的结果渲染展现到页面上
-
性能优化:可以利用防抖或节流,可以减少服务器压力
通过lodash实现节流或防抖,引入loadash实现防抖,例如:
import _ from 'lodash'
template:
<el-input placeholder="请输入内容" @input="searchUser" v-model.trim="pageinfo.query" class="searchInput">
JS:
searchUser:_.debounce(function() {
//获取去除空格后的输入内容
// this.pageinfo.query=this.pageinfo.query.trim()
//query.length===0代表搜索全部用户列表,否则搜索包含有关键字的用户列表
// let _this=this;
this.getUserList()
},300),
-
添加用户
- 添加验证规则步骤 ```
1.给el-form绑定 :rules属性,例如:
具体规则: userRules:{ username:[ { required: true, message: '请输入用户名', trigger: 'blur' }, { min: 6, max: 30, message: '长度在 6 到 30 个字符', trigger: 'blur' } ] }
2.通过prop关联在验证的input框
3.给触发事件的元素添加验证方法 this.$refs.adduser.validate(valid=>{ if (valid) { //向后台添加用户数据 console.log('ok') } else { //验证失败 console.log('error submit!!'); return false; }
}) ```
可以结合star原则讲项目或项目中的某个模块
S:situation 项目背景 后台管理,电商用户比较多
T: task 任务 我负责的模块主要有搜索,登录,权限认证,商品管理。。。
A:action 具体如何步骤(思路)比如:我跟您说一下搜索我是怎么实现的吧
R: result 结果 提升了后台管理效率和减少服务器压力
二、表格的编辑和分配角色
- 修改用户状态
let result = await this.$http.put(
`users/${user.id}/state/${user.mg_state}`
);
console.log('result:',result)
let {
meta: { msg, status }
} = result.data;
if (status === 200) {
this.$message({
message: msg,
type: "success"
});
}else {
this.$message({
message: msg,
type: "error"
});
}
- 编辑用户信息
通过传递用户id调用指定接口修改用户信息
总结:
- 搜索功能(添加节流和防抖)
- 添加用户功能
- 修改用户状态功能
- 编辑用户信息(例如:修改邮箱,手机号)
再次重温接口封装(从微信小程序--vue一直在强调接口的封装)
axios官方github:https://github.com/axios/axios
/** * 删除单个用户 */ export function deleteUser(userid) { console.log('要删除的用户id:',userid); return request({ url: users/${userid}
, method: 'delete' }) }
```
## 二、分配用户角色
```
1.显示用户角色弹框
2.显示当前用户名
3.显示当前用户角色
当前用户id查找到用户角色
4.通过下拉框分配用户角色列表
```
三、封装面试屑导航组件
全局组件 可以在做任意位置使用
Vue.component('组件名',组件对象)
//引入面包屑组件
import myBrand from '@/components/brand_com'
//Vue全局面包屑组件
Vue.component(myBrand.name, myBrand)