美文网首页
Vue复杂模块请求管理v-loading

Vue复杂模块请求管理v-loading

作者: Luciena | 来源:发表于2022-01-11 11:32 被阅读0次

    背景

    在前端大型项目开发中,往往会遇到一个页面有n个组件,组件里面又有m个请求。最后“提交”或者“保存”的时候,如果请求没回来,你提交的数据可能都是你在data里定义的默认数据。
    这时候,明明用户没修改相关模块,你却将默认数据传给了后端,导致数据库里存入了错误数据。

    方案

    1.写一个请求类管理器,来管理网络请求
    2.请求进行时,loading遮罩整个页面
    3.请求完成时,去除loading,用户可正常操作

    具体代码

    src/utils/init.js

    // 请求状态管理类
    class RequestState {
        constructor() {
            this.map = {};
            this.callbackMap = {};
        }
        // 初始化 module-模块名称 nameList-请求列表
        init(module, nameList, cb) {
            if (this.callbackMap[module]) throw new Error('已经存在同名模块');
            if (module && Array.isArray(nameList) && nameList.length) {
                this.map[module] = [];
                this.callbackMap[module] = typeof cb === 'function' ? cb : function () {};
    
                nameList.forEach((item) => {
                    this.map[module] = this.map[module].concat({ name: item, status: false });
                });
            }
        }
        // 获取某个模块某个api的情况
        get(module, name) {
            if (this.map[module] && Array.isArray(this.map[module]) && this.map[module].length) {
                const item = this.map[module].find((i) => i.name === name);
                return item.status;
            }
        }
        // 获取某个模块的所有请求是否完成
        done(module) {
            if (Array.isArray(this.map[module]) && this.map[module].length) {
                const isNotDone = this.map[module].some((j) => j.status === false);
                if (!isNotDone) {
                    this.callbackMap[module](true);
                    delete this.map[module];
                    delete this.callbackMap[module];
                }
            }
        }
    
        // 更新某个模块某个api的情况
        update(module, name, status) {
            if (Array.isArray(this.map[module]) && this.map[module].length) {
                this.map[module].forEach((i) => {
                    if (i.name === name) i.status = status;
                });
                this.done(module);
            }
        }
    }
    
    export default new RequestState();
    
    
    

    src/App.vue

    <template>
        <div id="app" v-loading="loading">
            <Test :model="testData" />
        </div>
    </template>
    
    <script>
    import Test from './pages/test.vue';
    import RequestState from './utils/init';
    
    export default {
        name: 'App',
        components: { Test },
        data() {
            return {
                loading: true,
                testData: {}
            };
        },
        mounted() {
            setTimeout(() => {
                this.testData = {
                    name: 'lucien',
                    age: '18'
                };
                RequestState.update('App', 'module1', true);
            }, 2000);
            RequestState.init('App', ['module1', 'module2'], (done) => {
                this.loading = !done;
            });
        },
    };
    </script>
    
    <style lang="scss">
    </style>
    
    

    src/pages/test.vue

    <template>
        <div class="main">
            <h1>测试页面数据</h1>
            <div class="module1">
                <p>name: {{ model.name }}</p>
                <p>age: {{ model.age }}</p>
            </div>
            <div class="module2">
                <el-input v-model="address" placeholder="无"></el-input>
                <p>集合: {{ phone }}</p>
            </div>
        </div>
    </template>
    <script>
    import RequestState from '../utils/init';
    
    export default {
        props: {
            model: {
                type: Object,
                default: () => {}
            }
        },
        data() {
            return {
                phone: null,
                address: null
            };
        },
        mounted() {
            setTimeout(() => {
                this.phone = '136XXXX4321';
                this.address = 'beijing';
                RequestState.update('App', 'module2', true);
            }, 4000);
        }
    };
    </script>
    
    <style lang="scss" scoped></style>
    
    

    效果

    不加请求类状态管理

    4s后点击提交,提交的是正常数据,符合预期。
    2s内点击“提交”,提交的全部是默认数据,这显然不符合预期。


    1.gif
    填加请求类状态管理以及v-loading

    整个视图默认被loading罩住。请求4s后全部完成,此时清除loading,点击“提交”。数据被正常提交。


    1.gif

    相关文章

      网友评论

          本文标题:Vue复杂模块请求管理v-loading

          本文链接:https://www.haomeiwen.com/subject/xehvcrtx.html