美文网首页
Vue异步请求最佳实践

Vue异步请求最佳实践

作者: 九里 | 来源:发表于2019-07-23 14:06 被阅读0次

一、当前存在的问题

目前项目前端请求后台数据的方式是这样的:

  1. 页面中methoddispatchaction

  2. action调用mutation,请求axios

  3. 请求到数据后存储到state

  4. 页面中在computed中获取state,使用watch监听到数据变化之后做业务逻辑。

调用流程如图:


现在的请求方式

在当前的项目中,这样的调用方式可以解决异步请求,对于接口的响应速度也很快。但依然有着几点不足。

1.代码冗余

页面中的每一个请求都需要一个method,一个comuputed和一个watch。我们知道computed是计算属性,是Vue数据驱动的重要实现。但在计算属性里获取state这个操作并没有去"计算"。实际上是用了mapstate获取了全局的state,计算属性在这里成了一个state的容器。

2.业务逻辑依赖watch

我们知道watch是监听器,但是用监听器去监听计算属性(数据驱动的)的变化,是本末倒置了。可以看看Vue官方文档是如何描述监听的:

虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。

watch应该是作为computed的补充,而不是代替。所以当前的问题是大量的业务逻辑写在watch里,而不是在调用接口,数据返回之后立即处理

3.错误的mutation使用

为什么是错误的呢?我们先看看为什么会有上面两个错误的出现。当我们把axios写到mutation的时候,我们发现computed获取到state的数据不是同步的。

image

二、解决问题

我们理想的情况是希望页面调用method之后去请求axios,后端数据返回时立即进行业务处理,处理完成之后界面立刻响应渲染。另外请求出错的时候,我们也希望能有对应的处理。实现上述需求,需要使用Promise来解决。了解Promise的用法,可以参考这篇文章Promise使用详解

使用Promise之后的请求流程变为下图:


image

在当前的请求逻辑下,我们可能觉得很疑惑的一点是,为什么删除的时候需要使用state?按照Vue的定义,state应该是一个公共的变量,所以删除之后的数据我不需要保存到state,但是为了保持页面的响应我们只能使用state来保存,使用computed去获取state,使用watch去响应数据变化。这样的步骤明显是多余的,那么我们看看使用了Promise之后的代码是什么样的,这里以一个删除功能为例:
首先我们需要在action中写一个Promise,在Promise中调用axios。理论上我们可以在页面上直接调用axios,但是由于需要保持API接口与页面解耦,所以页面的method方法依然是调用action。

    actions:{
        /* 删除资源action,进行了HTTP请求状态的判断,页面请求该方法后需要进行处理*/
        async delResBaseInfo(context, id) {
            return new Promise(function(resolve, reject) {
                axios
                    .delete(`${api}/${id}`)
                    .then((response) => {
                        if (response.status == 200) {
                            resolve(Immutable.fromJS(response.data));
                        } else {
                            reject(Immutable.fromJS(response.data));
                        }
                    })
                    .catch(function(error) {
                        console.log(error);
                    });
            });
        }
    }

页面method的调用函数,里面包含了业务逻辑。

    // 删除数据,调用action的axios请求
        deletData(id) {
            this.loading = true;
            this.$store
                .dispatch('resourceBase/delResBaseInfo', id)
                .then((response) => {
                    if (response.get('code') == 1) {
                        this.getData();
                        this.loading = false;
                        successMessage(this, textStandard.deleteSuccess(''));
                    } else {
                        errorMessage(this, textStandard.deleteError(''));
                    }
                })
                .catch((error) => {
                    console.log(error);
                });
        },

使用了Promise之后的代码得到了简化,并且因为Promise的特性,异步问题也能完美解决。

相关文章

  • Vue异步请求最佳实践

    一、当前存在的问题 目前项目前端请求后台数据的方式是这样的: 页面中method中dispatch到action ...

  • vue 异步请求

    vue-router 异步请求 在实际的应用开发中,与后端交互,进行异步请求是很常见的需求 axios 请求 跨域...

  • vue 异步请求

    一、无参异步请求假设有这么一个场景:点击一个submit按钮,弹出对话框:确认/取消,点击确认,根据mock接口返...

  • 文章收藏

    vue中H5问题汇总移动端最佳实践前端知识图谱vue-cli4-configGraphQL入门前端异常处理最佳实践...

  • 异步编程最佳实践

    1.什么是异步? 先理清楚几个概念: 1)同步:请求需要立即返回结果。 2)异步:请求无需立即返回结果。 3)阻塞...

  • web页面缓存最佳实践

    更多请查考vue2.0 keep-alive最佳实践

  • # Vue全家桶之vue-resource &&

    异步请求组件,你也可以认为是异步请求的JS库,毕竟这也确实是封装了原生JS的AJAX库。目前vue-resourc...

  • JS async/await-ajax异步请求等待返回数据

    JS async/await-ajax异步请求等待返回数据 例子使用的是 axios 做ajax请求 在vue中使...

  • Vue.js报错—TypeError: Cannot read

    错误:name未定义 原因是ajax是一个异步请求在加载的 解决方法: 因为获取信息是异步请求,所以vue绑定...

  • 阿里云oss 前端+后台方式-前端部分el-upload

    vue注意 axios封装接口为异步请求,使用el-upload默认上传,在before-upload里请求需要使...

网友评论

      本文标题:Vue异步请求最佳实践

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