这是一个知识回顾性质的前后端分离项目的前端使用的知识点整理

本文只做知识分析

前端源码 :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")
                    }
                })
        }
    }
})