Vue2.x + axios 封装请求api

使用Vue时我们常使用axios搭配食用,网上很多教程推荐的方法是直接把axios挂在Vue实例下使用,类似这样

Vue.axios = _axios;
    window.axios = _axios;
    Object.defineProperties(Vue.prototype, {
        axios: {
            get() {
                return _axios;
            }
        },
        $axios: {
            get() {
                return _axios;
            }
        },
    });

然后在各个component中进行如下的使用

    export default {
        data() {
            return {
                notification: [],
                users: []
            }
        },
        methods: {
            getUser() {
                this.axios.get(....)
                        .then(...)
                        .catch(...);
            }
        }
    }

但是这样使用会有一个弊端,就是整个methods中充斥着一大堆的ajax请求代码

往往后台在返回数据时还会封装一层data上去

{"success":true,"msg":"SUCCESS","data":{...}}

那么methods中还需要每次都判断请求成功与否、提示信息的展示,以及将返回值的data提取出来

一段伟大的意大利面组件诞生了!

请求代码和组件的视图业务逻辑重度耦合的情况,非常不利于请求代码的复用(听说Vue 3会支持函数式的组合方法提高复用)

为了将ajax请求和组件本身的逻辑分离,可以将api相关接口抽取成独立的插件

import Vue from "vue";

const prefix = 'api';

const preHandleResponse = response => {
    if (response && response.data) {
        if (response.data.success) {
            return Promise.resolve(response.data);
        } else {
            return Promise.reject(response.data.msg);
        }
    }
    return Promise.reject('请求异常,请联系管理员');
};

const preHandleUri = uri => `/${prefix}/${uri}`;

const sendGet = (uri, params, option) => {
    return Vue.axios.get(preHandleUri(uri), {
        params: params,
        ...option
    }).then(response => preHandleResponse(response))
};

const sendPost = (uri, data, option) => {
    return Vue.axios.post(preHandleUri(uri), data, option)
        .then(response => preHandleResponse(response))
};

const sendPut = (uri, data, option) => {
    return Vue.axios.put(preHandleUri(uri), data, option)
        .then(response => preHandleResponse(response))
};

const sendPatch = (uri, data, option) => {
    return Vue.axios.patch(preHandleUri(uri), data, option)
        .then(response => preHandleResponse(response))
};

const sendDelete = (uri, data, option) => {
    return Vue.axios.delete(preHandleUri(uri), data, option)
        .then(response => preHandleResponse(response))
};

const api = {
    memo: {
        list(params) {
            return sendGet('memo', params);
        },
        save(data) {
            return sendPost('memo', data);
        },
        update(data) {
            return sendPut(`memo/${data.id}`, data);
        },
        del(id) {
            return sendDelete(`memo/${id}`);
        }
    },
}

const APIPlugin = {
    install(Vue, options) {
        Object.defineProperties(Vue.prototype, {
            $api: {
                get() {
                    return api;
                }
            },
        });
    }
};

Vue.use(APIPlugin);

export default api;

这样就可以很方便的在component中对请求进行使用,同时避免代码意大利面化

this.$api.memo
    .list(Object.assign({}, {
        pageNum: this.grid.pageNum,
        pageSize: this.grid.pageSize
    }, this.queryForm))
    .then(result => {
        this.grid.data = result.data.rows;
        this.grid.total = result.data.total;
        this.grid.loading = false;
    })

可以看见,由于在api.js中我们已经将data提取出来,也对success字段作了判断,组件中的请求逻辑已经简化了许多

同时,还可以非常方便的定义prefix,即api的前缀路径,搭配一些后台的api-gateway将非常方便!

你可能感兴趣的:(Vue)