react & vue & angular

vue ---- 封装axios中的loading

2022-09-30  本文已影响0人  牛会骑自行车

上篇文章封装的axios只提到了当获取数据时(用在列表的情况比较多)的loading,其他调取接口时(比如删除、提交)需要的禁用按钮并没有涉及.这篇进行补充~目前没发现有坑emmm
涉及到的知识点有点杂😂ES6中的类,原生js中的创建元素、添加类名儿、插入元素啥的..

  1. createLoading使用到的是element-ui中loading服务啥的,文档位置https://element.eleme.cn/#/zh-CN/component/loading#options搜“服务”
  2. SubmitButton使用了ES6中的类创建啥的..(原谅我真的不会使用计算机的专业术语😂但确实是这么个东西~)

代码 ⬇️

/**
 * @param {string} url 
 * @param {object} params
 * @param {string} method 
 * @param {string | element} container 
 * @param {function}  buttonDisabled
 * @returns 
 */
export default function (url, params = {}, {
    method = 'get',
    container = '',
} = {}) {
    let isLoading = container !== null && typeof container !== 'undefined' && container !== '';
    // method === get ? createLoading(container) : new SubmitButton(container);
    // 判断条件: method \ isLoading 
    // 如果container存在,则进行列表加载动画或按钮禁用,不存在则为空
    // 接口调用一般有两种形式,一种是获取数据,另一种是上传数据; 
    // 一般我们用到的只有get是获取数据————使用列表加载, put\post\delete都适用按钮禁用
    let loading = isLoading ? method === 'get' ? createLoading(container) : createSubmitButton(container) : '';

    let data = method === 'get' || method === 'delete' ? {
        params
    } : params;

    return new Promise((resolve, reject) => {
        axios[method](url, data).then(response => {
            if (response.status === 0) resolve(response.data)
            else reject(response.msg)
            setTimeout(() => {
                isLoading && loading.close();
            }, 4000)
        }).catch(error => {
            console.error(error, 'GET api/index.js')
            reject('网络溜走啦~~');
            setTimeout(() => {
                isLoading && loading.close();
            }, 4000)
        });
    })
}

/**
 * 使用element-ui中的loading实例化啥的
 * @param {string | element} target 
 * @returns 
 */
function createLoading(target) {
    // 判断传入的target
    // 如果是字符串则用js获取该元素,如果是元素则直接使用
    let container = typeof target === 'string' ? document.getElementById(target) : target;

    let loadingInstance = Loading.service({
        target: container,
        fullscreen: false,
        text: "加载中....",
        spinner: "el-icon-loading"
    });

    return loadingInstance;
}
/**
 * 提交按钮实例
 */
class SubmitButton {
    constructor(idName) {
        // 获取提交按钮
        this.el = document.getElementById(idName);
        // 创建一个在loading状态下会用到的i标签
        this.loadingEl = document.createElement('i');
    }
    toDisabled() {
        // 观察el-button的loading为true时的状态: 
        // 加了类名 "is-loading"和一个类名为"el-icon-loading"的i标签
        this.el.classList.add('is-loading');
        this.loadingEl.className = 'el-icon-loading';

        let textEl = this.el.getElementsByTagName('span')[0];
        this.el.insertBefore(this.loadingEl, textEl);
    }
    close() {
        // 取消在toDisabled中添加的东西,恢复按钮状态
        this.el.removeChild(this.loadingEl);
        this.el.classList.remove('is-loading');
    }
}
/**
 * @param {string} idName 
 * @returns 
 */
function createSubmitButton(idName) {
    // 创建SubmitButton实例
    let submitButton = new SubmitButton(idName);
    // 执行禁用方法
    submitButton.toDisabled();

    return submitButton;
}

tada~~~一个封装好的axios就可以连带loading们一起愉快地使用啦

上一篇 下一篇

猜你喜欢

热点阅读