最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • vue中@Action的异常处理你了解吗?(实践)

    正文概述 掘金(git-Dignity)   2021-03-07   1149

    前言

    • 音乐博客】上线啦!
    • 个人文档点击查看你的代码是否规范呀~
    • 个人文档VuePress搭建项目组件文档教程!
    • 终于熬到星期六日,睡到中午精神饱满,打开音乐博客想听会歌,发现登陆按钮一直在转,就算密码输错了,也不应该一直在转,便一探究竟。

    星期三女朋友和堂姐在家做的美食,走到四五楼闻到香味:香死啦~

    vue中@Action的异常处理你了解吗?(实践)

    回味登陆CODE

    Login.vue

    「现象」:密码输入错误。

    「分析」:应该是接口没有返回data,只是在if(data) { this.loading = false },所以就算没有data也需要设为false;或者走了catch

    当然我看到页面这种情况,也只是猜的,因为我也好久没看到之前写的登录逻辑。

    先来欣赏之前写的代码。

    /**
    * Login.vue
    * 登陆按钮点击事件
    */
    private handleLogin() {
        (this.$refs.loginForm as ElForm).validate(async (valid: boolean) => {
          if (valid) {
            this.loading = true;
            await UserModule.Login(this.loginForm);

            setTimeout(() => {
              this.loading = false;
            }, 0.5 * 1000);

            this.$router.push({
              path: this.redirect || "/",
              query: this.otherQuery
            });
          } else {
            return false;
          }
        });
      }

    「欣赏心得:」

    if (valid)里面不管登录成功或者失败,都将loading视为false,这是对的;但是没有用一个变量接收这个结果await UserModule.Login,如果一直await不到结果,就不会走下面的代码,不管成功失败都跳路由(应该是成功的时候才跳路由吧,之前真是能完成功能就好,随便应付)

    继续走下去,等会在上修改后的代码。

    Store.user.ts

    Login.vue上面的代码看,主要看这段代码:await UserModule.Login(this.loginForm);

      @Action
      public async Login(userInfo: { username: string, password: string }) {
        let { username, password } = userInfo
        username = username.trim()

        const {data}  = await login({ username, password })
        setToken(data.accessToken)
        this.SET_TOKEN(data.accessToken)
        this.SET_NAME(username)
      }

    「欣赏心得:」

    没有try、catch住await login(),没有报错了,下面就不会执行下去。

    我打印了data,发现打印不出来,很明显await login()的时候便报错了。

    login请求

    继续追究下去,login请求

    // Response interceptors
    service.interceptors.response.use(
      (response) => {
        const res = response.data
        if (res.code !== 20000) {
          return Promise.reject(new Error(res.message || 'Error'))
        } else {
          return response.data
        }
      }

    发现走的是return Promise.reject(new Error(res.message || 'Error')),因为code:20001

    @Action({rawError:true})

    我打开控制台,发现:

    vue中@Action的异常处理你了解吗?(实践)

    百度ERR_ACTION_ACCESS_UNDEFINED: Are you trying to access this.someMutation() or this.someGetter inside

    「解决方案」

    @Action({rawError:true}):即暴露出原生 error。

    最后try、catch下错误就解决了错误。

    写在这基本就完结了问题错误。

    但是我相信很多同学跟我一样,想知道@Action({rawError:true})是干嘛的,那请继续往下看我分析。

    vue中@Action的异常处理

    我们先来看一个知识点

    • 在某行代码有错误抛出后,后面的代码都不会被执行,直接阻断
    • try-catch 语句里的代码有一行有错误,后面也阻断,但是跳出 catch 语句后面的代码依然可以执行,因为抛出的错误被 catch 接到了
    try {
        test()
        console.log('after-test');
      } catch (e) {
        console.log('catch-error', e);
      }
      console.log('after-trycatch');
      function test() {
        throw new Error()
      }
    vue中@Action的异常处理你了解吗?(实践)

    test函数执行,throw Error错误,被catch接住,便打印了catch-error + 抛出的错误,继续走下面的输出after-trycatch

    OK,相信有了上面的了解,再来看下面的代码,会更清楚点。

    「store.user」

      @Action
      public async Login(userInfo: { username: string, password: string }) {
        let { username, password } = userInfo
        username = username.trim()
        this.SET_NAME(username)
      
        const {data}  = await login({ username, password })
        setToken(data.accessToken)
        this.SET_TOKEN(data.accessToken)
      }

    「Login.vue」

    private handleLogin() {
      (this.$refs.loginForm as ElForm).validate(async (valid: boolean) => {
        if (valid) {
          this.loading = true;
          try {
            await UserModule.Login(this.loginForm);
          } catch (e) {
            console.log(e);
          }

          setTimeout(() => {
            this.loading = false;
          }, 0.5 * 1000);
        } else {
          return false;
        }
      });
    }
    vue中@Action的异常处理你了解吗?(实践)

    「现象」:此时 catch 住的 error 并非项目里由 axios 抛出的 requestError 类型(该类型包含 isHandled 属性)

    「打印 error」:抛出两个异常

    • 一个是ERR_ACTION_ACCESS_UNDEFINED
    • 一个是error:无法链接或出错。其中第二个是 requestError 类型的。但是基于上面知识点中所说的代码里 throw error,后面的代码应该不执行的,但是却执行了 setToken(data.accessToken),从而导致 mutation 报错,说明@Action 做了一些工作。

    「分析源码」: 那么页面 catch 住的是什么 error 呢,查看vuex-module-decorators中关于@Action的源码:

    vue中@Action的异常处理你了解吗?(实践)

    「可知」:@Action 在不给 rawError 置为 true 时,会 new 一个新的 Error,并且带上 aciton 里抛出的错误,包裹到一起抛出,因此页面 catch 住的 error 是@Action 抛出的错误,打印就会看到原 error 的信息

    「总结」:这也就是为什么页面上把两个错误一起抛出来了。一个是action抛出来、一个是请求走new thorw抛出来,合并打印出来。

    「解决方法」: 加rawError属性,@Action({rawError:true}),即暴露出原生 error。

    好,我们加上试一下

    vue中@Action的异常处理你了解吗?(实践)

    可以看到只剩下原生的error,action的错误不会抛出来了。

    Login.vue代码

    store.user代码

    !__!:
    一天一行代码,干饭啦!

    原文链接

    juejin.im/post/689011…

    参考文档

    ERR_ACTION_ACCESS_UNDEFINED: Are you trying to access this.someMutation() or this.someGetter inside

    ue中@Action的异常处理


    起源地下载网 » vue中@Action的异常处理你了解吗?(实践)

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元