前言
- 【音乐博客】上线啦!
- 个人文档点击查看你的代码是否规范呀~
- 个人文档VuePress搭建项目组件文档教程!
- 终于熬到星期六日,睡到中午精神饱满,打开音乐博客想听会歌,发现登陆按钮一直在转,就算密码输错了,也不应该一直在转,便一探究竟。
❝星期三女朋友和堂姐在家做的美食,走到四五楼闻到香味:香死啦~
❞
回味登陆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})
我打开控制台,发现:
百度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()
}
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;
}
});
}
「现象」:此时 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的源码:
「可知」:@Action 在不给 rawError 置为 true 时,会 new 一个新的 Error,并且带上 aciton 里抛出的错误,包裹到一起抛出,因此页面 catch 住的 error 是@Action 抛出的错误,打印就会看到原 error 的信息
「总结」:这也就是为什么页面上把两个错误一起抛出来了。一个是action抛出来、一个是请求走new thorw抛出来,合并打印出来。
「解决方法」: 加rawError属性,@Action({rawError:true})
,即暴露出原生 error。
好,我们加上试一下
可以看到只剩下原生的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的异常处理
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!