这是一个知识回顾性质的前后端分离项目的前端使用的知识点整理
本文只做知识分析
前端源码 :https://gitee.com/leo-heng/ssm_test_front_end
后端源码 :https://gitee.com/leo-heng/ssm_test_back_end
目录
- 目录结构
- js
- employeeAxios.js
- index.js
- loginAxios.js
- login.js
目录结构
前端页面使用axios处理请求和响应
页面
├── css //css
│ ├── AdminLTE.min.css
│ ├── bootstrap.min.css
│ ├── dialog.css
│ ├── font-awesome.min.css
│ ├── index.css
│ ├── loginRegister.css
│ ├── zpageNav.css
│ └── _all-skins.min.css
├── fonts //fonts
│ ├── fontawesome-webfont.eot
│ ├── fontawesome-webfont.svg
│ ├── fontawesome-webfont.ttf
│ ├── fontawesome-webfont.woff
│ ├── fontawesome-webfont.woff2
│ └── FontAwesome.otf
├── js //js
│ ├── adminlte.min.js
│ ├── axios.min.js
│ ├── bootstrap.min.js
│ ├── jquery.min.js
│ ├── vue.min.js
│ └── zpageNav.js
├── myjs //自定义js
│ ├── employeeAxios.js //自定义axios
│ ├── index.js // 主页js
│ ├── login.js // 登录页js
│ └── loginAxios.js //自定义axios
├── index.html //数据页面
└── login.html //登录页面
js
employeeAxios.js
相关知识点 :
-
employeeAxios
为自定义axios , 用于在请求前自动添加请求地址baseURL
-
baseURL
表示使用某个自定义请求时会自动在请求前添加请求地址 -
withCredentials=true
默认值为false
, 表示请求时携带cookie , 由于本项目是一个前后端分离项目 , 因此需要携带cookie实现跨域 , 所以将withCredentials
设置为true - 请求拦截器和响应拦截器用于对请求和响应做加工
- 请求拦截器 , 发生于请求前 , 一共有2个参数 , 一个用于请求成功 , 一个用于请求失败
- 响应拦截器 , 发生于相应后 , 一共有2个参数 , 一个用于响应成功 , 一个用于响应失败
- 由于js只需获取请求中的数据 , 因此可以在响应拦截器中对数据加工 , 最后只将请求中的数据返回给接收函数
- 在响应拦截器中根据请求返回的状态码判断接下来如何执行
代码 :
let employeeAxios = axios.create({
baseURL: 'http://localhost:8080/',
timeout: 5000,//设置超时时间
withCredentials: true,//设置请求时携带cookie , 默认值为false
})
//请求拦截器 , 发生于请求前 , use共有2个参数 , 一个用于请求成功 , 一个用于请求失败
employeeAxios.interceptors.request.use(request => {
// 在请求发生前动态添加一个请求地址
// request.baseURL = "http://localhost:8080/";
return request;
}, err => {
// 该返回的数据则是axios.catch(err)中接收的数据
return Promise.reject(err)
})
// 响应拦截器 , 发生于响应后 use共有2个参数 , 一个用于响应成功 , 一个用于响应失败
employeeAxios.interceptors.response.use(response => {
// 请求成功对响应数据做处理
let {status, message, data} = response.data;
// let data=response.data.data
//根据返回的状态码判断是否继续向下执行
//返回的数据则是axios.then(response)中接收的数据
if (status == 20000) {
return data
}
if (status == 44444) {
console.log("=====")
location.replace("./login.html")
}
}, err => {
// 该返回的数据则是axios.catch(err)中接收的数据
return Promise.reject(err)
})
index.js
相关知识点 :
-
el
: 提供一个已经在页面上存在的DOM实例 , 作为vue的挂载目标 -
data
: 指定设置当前vue实例所使用的数据,data的值可以是一个对象 -
created(){}
: creat函数在vue对象创建完成后自动调用 - 为了解决axios请求地址需要多次输入问题 , 在vue对象后可以创建一个axios的默认请求地址
- 每次请求都会自动将后续地址拼接到
baseURL
后 , 每次请求只需要选择访问的controller
即可 , 不要在前面添加/
- 产生的问题 : 每个js都需要设置一个
baseURL
当有多个时需要设置多个 , 因此才需要设置自定义axios , 如 :employeeAxios.js``loginAxios.js
中设置的
mehtods:{}
: 给vue定义方法
-
findAll()
: 查询所有 -
pageChange()
: 点击分页的回掉函数 choseAvatar()
: 异步上传头像到文件服务器
-
e.target.files[0]
获取选择的第一张图片 -
new FormData
创建表格对象 , 用于异步方式文件上传 - axios设置post请求的第三个参数为
{headers:{"Content-Type":"multipart/form"}}
实现文件上传 , 否则上传的只是一个json字符串
-
addOrEdit()
: 确认添加按钮绑定的方法 , 根据判断上传表格是否携带用户id , 来实现修改和添加的切换 -
addEmployee()
: 添加员工 , 需要注意 : 头像图像上传的是它的URL地址 , 因此可能会超过数据库的限制长度 , 可以做校验避免 , 也可以修改数据库的限制避免 -
findById()
: 根据id查询员工 , 用于修改 , 如果查询到的用户有头像则显示头像 , 没有头像则不展示或者展示默认图片 -
updateEmployee()
: 修改员工 chooseDeleteItem()
: 将选择员工加入数组 , 用于批量删除
e.target.checked
: 判断复选框是否被选择 , 如果选中则为ture
否则为false
- 如果选中复选框则将id存入数组
- 没有选中复选框则将id从数组中删除
-
batchDeleteByIds()
: 批量删除员工 doDeleteBtn()
: 删除单个员工
- 通过页面ref属性获取页面中的dom元素
- 获取的dom元素是一个伪数组 , 不能直接使用数组中的方法 , 除非借调
- elementsByClassName有版本兼容问题 , ie8前不可使用
- 如果考虑版本兼容问题 , 可以选择调用子元素来获取选择框
-
importExcel()
: 上传excel表格
代码 :
let vue = new Vue({
el: "#app",
data: {
tableData: [],//展示的表单数据
currentPage: 1,//当前分页
pageSize: 2,//每页数据条数
total: 0,//数据总条数
imgUrl: "",//头像地址
employeeData: {},//提交表单数据
deleteIds: [],//将被删除的id
deleteNames: []
},
created() {//created函数在vue对象创建完成后自动调用
//解决axios请求地址需要多次输入问题 , 在vue对象创建后设置一个axios的默认请求地址 ,
//每次请求会自动将后续地址拼接到baseURL后面
//只需要选择访问的controller即可 , 不需要在前面添加'/' ,
//产生的问题 : 每个js都需要设置一个baseURL当有多个时需要设置多个
//axios.defaults.baseURL='http://localhost:8080/employee'
this.findAll()
},
methods: {
findAll() {
employeeAxios.get(`employee?currentPage=${this.currentPage}&pageSize=${this.pageSize}`)
.then(response => {
let {total, list} = response;
this.tableData = list;
this.total = total;
})
},
/**
* 点击分页回调函数
*/
pageChange(page) {
this.currentPage = page;
this.findAll();
console.log(this.tableData[0].employeeId)
},
choseAvatar(e) {
let file = e.target.files[0];
let formData = new FormData;
formData.append("avatar", file);
//设置post的第三个参数为 : {headers:{"Content-Type":"multipart/form"}} 实现文件上传 , 否则上传的只是一个json字符串
employeeAxios.post("common/upload", formData, {headers: {"Content-Type": "multipart/form"}})
.then(response => {
//response为上传图片后返回的地址
//tmgUrl展示上传后的图片
//将上传后的图片赋值给employeeData , 将上传的图片的地址保存到数据库中
this.imgUrl = response;
this.employeeData.employeeAvatar = this.imgUrl;
})
},
/*
* 确认按钮 , 添加或者修改
* 根据employeeData的employeeId是否有数据判断是新增还是修改
* employeeId有值是修改 无值是添加
* */
addOrEdit() {
if (this.employeeData.employeeId) {
this.updateEmployee();
} else {
this.addEmployee();
}
},
/*
* 添加员工
* */
addEmployee() {
//上传的地址可能会超过数据库的限制长度 , 可以做校验 , 也可以修改数据库的限制
employeeAxios.post(`employee`, this.employeeData).then(() => {
this.findAll();
})
},
findById(id) {
employeeAxios.get(`employee/${id}`).then(response => {
this.employeeData = response;
//如果上传过头像 , 才将头像展示 , 否则不展示或展示默认图片
if (response.employeeAvatar) {
this.imgUrl = response.employeeAvatar;
} else {
this.imgUrl = '';
}
})
},
/*
* 修改
* */
updateEmployee() {
employeeAxios.put(`employee`, this.employeeData).then(() => {
this.findAll();
})
},
chooseDeleteItem(id, name, e) {
//e.target.checked获取复选框是否被选择 , 选中为true , 未选中为false
if (e.target.checked) {
//将id存入deleteIdes
this.deleteIds.push(id);
this.deleteNames.push(name)
} else {
//将id从deleteIds中删除
//this.deleteIds.findIndex(item => item == id) 获取id在deleteIds中的数组下标
//this.deleteIds.splice(index,1) 从第index位开始删除 , 删除1位
this.deleteIds.splice(this.deleteIds.findIndex(item => item == id), 1)
this.deleteNames.splice(this.deleteNames.findIndex(item => item == name), 1)
}
},
batchDeleteByIds() {
employeeAxios.delete(`employee/${this.deleteIds}`).then(() => {
this.findAll();
this.deleteIds = [];
})
},
doDeleteBtn(id) {
//通过页面ref属性获取页面中的dom元素
//通过this.$refs操作页面中的ref元素
//这里获取的对象是一个伪数组 , 不能直接使用数组当中的方法 , 除非借调
//注意 : elementsByClassName有版本兼容问题 , 在ie8前不可使用
//如果考虑版本兼容性问题 , 可以选择调用子元素来获取选择框
var elementsByClassName = this.$refs.tbody.getElementsByClassName("idCheckBox");
for (let i = 0; i < elementsByClassName.length; i++) {
elementsByClassName[i].checked = false;
}
this.deleteIds = [];
this.deleteIds.push(id);
},
importExcel(e){
let file = e.target.files[0];
let formData = new FormData;
formData.append("excel", file);
//设置post的第三个参数为 : {headers:{"Content-Type":"multipart/form"}} 实现文件上传 , 否则上传的只是一个json字符串
employeeAxios.post("common/importExcel", formData, {headers: {"Content-Type": "multipart/form"}})
.then(response => {
})
}
/*
出现的问题1 :
每个请求都要添加http://localhost:8080/employee , 如果后端修改 , 不方便修改
解决方案 :
1. 设置全局BaseURL
axios.defaults.baseURL='http://localhost:8080/employee'
产生的问题 : 一个js页面需要设置一个baseURL当有很多个js时需要设置多个
2. 每次请求的时候 , 动态添加BaseURL
通过请求拦截器 , 在请求发送前动态添加baseURL
3. 自定义axios(推荐使用)
设置自定义axios , 自动拼接请求地址
出现的问题2 :
每个controller的返回数据都在response.data中 , 想要获取需要先获取data再获取里面的值
解决方案 :
使用一个内容 , 把不要的东西过滤掉 , 把要的东西往后传递
*/
}
})
loginAxios.js
相关知识点 :
-
loginAxios
是一个自定义axios , 用于在请求前自动添加请求地址baseURL
代码 :
let loginAxios = axios.create({
baseURL: 'http://localhost:8080/',
timeout: 5000,//设置超时时间
withCredentials: true,//设置请求时携带cookie , 默认值为false
})
login.js
相关知识点 :
- 基本都包含在index.js中了
代码 :
let vue = new Vue({
el: "#app",
data: {
formData: {
phone: '17719211641',
code: ''
}
},
methods: {
getCode() {
//获取手机验证码
loginAxios.get(`common/getCode?phone=${this.formData.phone}`)
.then(response => {
console.log(response)
})
},
doLogin() {//将对象作为参数提交给后台 , 默认传递JSON , 放到请求体中
loginAxios.post(`common/doLogin`, this.formData)
.then(response => {
console.log(response)
let {status, message} = response.data;
if (status == 20000) {
location.replace("./index.html")
}
})
}
}
})