实习记录:前端post/get封装、api接口统一管理

本文为笔者实习期间学习记录

vue前端post/get封装与api接口统一管理

一、功能描述

采用原本使用axios的post/get与后端交互是这样的:

 // 增加数据
    add() {
      this.$axios
        .post("/add", {
            requestHead: {
              version: '1',
              businessType: '1',
              deviceId: '1',
              deviceType: '1',
              encryption: '1'
            },
            body: this.dictionary
        })
        .then(resp => {
          // 成功增加数据后刷新页面
          if (resp && resp.status === 200) {
            this.$notify({
              title: "成功",
              message: "数据已成功插入",
              type: "success",
              duration: 1500
            });
            this.loadDictionaries();
            this.dialogDictionary = false;
          }
        })
        .catch(() => {
          this.$message({
            type: "error",
            message: "数据插入失败",
            duration: 1000
          });
        });
    },

即,在需要与后端交互时,发出post/get请求,这样的情况下,url很分散,如果后端地址发生改变,前端就需要进行定位找到函数后再修改,很不方便. 另外一点是,由于发送的是自定义报文,请求头都是一样的,没必要每次请求都重复写. 所以将post/get方法以及自定义报文封装起来,api地址写在一个文件里统一管理,并且通过引用的方式在不同的vue文件里调用.

二、设计思路
  1. Axios的封装
    Axios是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中. 简单来说主要是用于向后台发起请求.
    关于Axios,可以查看Axios中文文档.

    在src下的utils文件夹新建basedataRequest.js,用于封装Axios的post和get请求.

    (1) 引入axios

    // 在basedataRequest.js中引入axios
    import axios from 'axios'; // 引入axios
    

    (2) 设置baseUrl和超时时间
    通过axios.defaults.baseURL设置默认的基础地址,减少冗余.
    通过axios.defaults.timeout设置默认的请求超时时间。例如超过了20s,就会告知用户当前请求超时,请刷新等.

    axios.defaults.timeout=50000;
    axios.defaults.baseURL="http://localhost/boss-bes-basedata-center/api/";
    

    (3)请求拦截和响应拦截
    axios里面可以设置拦截器 ,可以在我们正式请求发送之前做一些事情. 拦截器分请求拦截器和响应拦截器.
    拦截器常见的用途是,对token的绑定进行统一的管理.
    我们在前后端交互时使用token进行鉴权验证,首次请求后台返回token给前端,前端将token保存到本地,之后的每次发出的请求都需要带上这个token. 如果手动加上的话未免太过麻烦了,这时候就可以使用拦截器,在请求发出之前自动加上token信息.

    // request拦截器
    service.interceptors.request.use(config => {
     //此处进行token等数据处理
    return config
    }, error => {
      // 这里进行异常处理
     Promise.reject(error)
    });
    
    // respone拦截器
    service.interceptors.response.use(
      response => {
       const res = response.data;
       if (res.code !== 200) {
    	  //此处进行异常处理
    	  return Promise.reject(res);
        }
        return response
      },
      error => {
       //此处进行异常处理
       return Promise.reject(error)
      }
    );
    

    (4)封装post和get方法

    /**
    * 封装post请求
    * @param url 请求地址
    * @param data 请求参数
    * @returns {Promise} 返回参数
    */
    
    export function post(url,data = {}){
     return new Promise((resolve,reject) => {
       axios.post(url,data)
            .then(response => {
              resolve(response.data);
            },err => {
              reject(err)
            })
     })
    }
    

    get方法类似

  2. 封装自定义报文
    新建requestUtils.js文件.
    头部为固定的公用数据.
    将传入的参数作为body,加上头部requestHead的数据后返回.

    /**
     * common request util
     * 从coookies 获取公共数据
     * @param params
     * @returns {{head: {deviceType, crypt, businessType, version, 	deviceId, token}, body: *}}
     */
    export function commonRequestUtil(params) {
    return {
     	 requestHead: {
      	 	version: head.version,
      	 	token: getToken(),
       	 	businessType: head.businessType,
        	deviceId: head.deviceId,
       	 	deviceType: head.deviceType,
       	 	crypt: head.crypt
     	 },
    	  body: params
    	}
    }
    
  3. Api统一管理
    新建index.js文件,引入上面的basedataRequest.js和requestUtils.js,

    export const loadDictionaryIdAndValueList=p
    =>post('/Dictionary/getDictionaryListByName',commonRequestUtil(p));
    

    上面定义了一个loadDictionaryIdAndValueList方法,这个方法有一个参数p,p是我们请求接口时携带的参数对象。而后调用了之前封装的post方法,post方法的第一个参数是请求地址url,第二个参数是进行报文封装后body为p的参数,最后通过export导出该方法使得其他文件可以引用.

三、代码实现
  • index.js
import request from '../utils/basedataRequest';
import { post, put, deletes, get } from '../utils/basedataRequest'
import {commonRequestUtil} from '../utils/requestUtils'
export const fetchData = (query) => {
    return request({
        url: '/ms/table/list',
        method: 'post',
        data: query
    })
}

/*深拷贝,复制一份数据解除双向绑定,使dialog数据改变时row的数据不变*/
export const deepClone=obj=>{
    let _obj = JSON.stringify(obj),
        objClone = JSON.parse(_obj);
    return objClone
}

/*api接口统一管理 */

//---------------------数据字典api------------------------//
export const loadDictionaryIdAndValueList=p=>post('/Dictionary/getDictionaryListByName',commonRequestUtil(p));
export const queryDictionary=p=>post('/Dictionary/query',commonRequestUtil(p));
export const addDictionary=p=>post('/Dictionary/add',commonRequestUtil(p));
export const deleteDictionaries=p=>post('/Dictionary/delete',commonRequestUtil(p));
export const updateDictionary=p=>post('/Dictionary/update',commonRequestUtil(p));
  • basedataRequest.js
import axios from 'axios';
import {Loading}from 'element-ui'      //****在这里引入Loading组件****

axios.defaults.timeout=50000;
axios.defaults.baseURL="http://localhost/boss-bes-basedata-center/api/";

//request拦截器
service.interceptors.request.use( config => {
  //请求前到请求到数据这段时间用加载动画来代替,以服务方式调用
  //     let loading = Loading.service({
  //         fullscreen: true,
  //         text: '拼命加载中...',
  //     });
    return config;
}, error => {
    console.log(error);
    // let loading = Loading.service({});
    // loading.close();
    return Promise.reject();
})

//response拦截器
service.interceptors.response.use(response => {
  // let loading = Loading.service({});
  // loading.close();
    if(response.status === 200){
        return response.data;
    }else{
        Promise.reject();
    }
}, error => {
    console.log(error);
    return Promise.reject();
})



/**
 * 封装get方法
 * @param url
 * @param data
 * @returns {Promise}
 */

export function fetch(url,params={}){
    return new Promise((resolve,reject) => {
      axios.get(url,{
        params:params
      })
      .then(response => {
        resolve(response.data);
      })
      .catch(err => {
        reject(err)
      })
    })
  }
  
  
  /**
   * 封装post请求
   * @param url
   * @param data
   * @returns {Promise}
   */
  
   export function post(url,data = {}){
     return new Promise((resolve,reject) => {
       axios.post(url,data)
            .then(response => {
              resolve(response.data);
            },err => {
              reject(err)
            })
     })
   }
  
  
   /**
   * 封装put请求
   * @param url
   * @param data
   * @returns {Promise}
   */
  
  export function put(url,data = {}){
    return new Promise((resolve,reject) => {
      axios.put(url,data)
           .then(response => {
             resolve(response.data);
           },err => {
             reject(err)
           })
    })
  }

  
  • 在vue文件中使用
    使用import从index.js引入要使用的方法,然后可在本地方法中直接使用,参数为body部分,无需再写出头部以及url信息.
<script>
	import {
		loadDictionaries,
		addDictionary,
		updateDictionary,
		deleteDictionaries,
		queryDictionary,
		deepClone
	} from "../../api/index";
	export default {
		
		methods: {
			// 增加数据
			add() {
				this.$refs.Dictionary.validate((valid) => {
					if (valid) {
						addDictionary(this.dictionary)
							.then(resp => {
								// 成功增加数据后刷新页面
								if (resp && resp.responseHead.code === "0") {
									this.$notify({
										title: "成功",
										message: "数据已成功插入",
										type: "success",
										duration: 1500
									});
									this.loadDictionaries();
									this.dialogDictionary = false;
								} else if (resp) {
									this.$notify({
										title: "失败",
										message: "错误码:" + resp.responseHead.code + " 错误信息:" + resp.responseHead.message,
										type: "error",
										duration: 1500
									});
								}
							})
							.catch(() => {
								this.$message({
									type: "error",
									message: "数据插入失败",
									duration: 1500
								});
							});
					}
				});
			},
		
	
</script>
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值