用 vuex 设置错误处理有点费力。似乎有很多方法可以做到这一点,而且关于正确错误处理的文档很少。我一直在尝试四种替代方案,但还没有找到令人满意的解决方案。
备选方案 1 - 捕获和处理组件上的错误
在 页面/login.vue 中:
export default {
methods: {
onLogin() {
this.$store.dispatch('auth/login', {
email: this.email,
password: this.password,
}).then(() => {
this.$router.push('/home');
}).catch((error) {
// handle error in component
});
},
},
}
在 商店/auth.js 中:
export const actions = {
login({ commit }, { email, password }) {
return this.$axios.post('/api/login', {
email,
password,
}).then((res) => {
doSomething(res);
});
},
}
优点
- 唔。
缺点
- 未处理和存储在 vuex 中的错误。
- 在组件方法中引入大量样板代码。
备选方案 2 - 在 vuex 中捕获和处理错误
在 页面/login.vue 中:
export default {
methods: {
onLogin() {
this.$store.dispatch('auth/login', {
email: this.email,
password: this.password,
}).then(() => {
this.$router.push('/home');
});
},
},
}
在 商店/auth.js 中:
export const actions = {
login({ commit }, { email, password }) {
return this.$axios.post('/api/login', {
email,
password,
}).then((res) => {
doSomething(res);
}).catch((error) => {
// store error in application state
commit('SET_ERROR', error);
});
},
}
优点
- 任何组件的 vuex 都可以访问错误对象
- 可以在布局中使用反应性错误组件,当错误状态发生变化时会显示出来。
缺点
- 我不确定是否有办法跟踪错误的来源,它是从哪个组件抛出的。
备选方案 3 - 使用 axios 拦截器捕获错误
在 插件/axios.js 中:
export default function({ $axios, store }) {
$axios.onError(error => {
store.dispatch('setError', error);
});
}
在 页面/login.vue 中:
export default {
methods: {
onLogin() {
this.$store.dispatch('auth/login', {
email: this.email,
password: this.password,
}).then(() => {
this.$router.push('/home');
});
},
},
}
在 商店/auth.js 中:
export const actions = {
login({ commit }, { email, password }) {
return this.$axios.post('/api/login', {
email,
password,
}).then((res) => {
doSomething(res);
});
},
}
优点
- 全局错误处理
- 无需捕获 vuex 或组件中的错误
- 没有样板代码
缺点
- 所有异常都未处理,这意味着未捕获非 axios 错误。
备选方案 4 - 自定义错误插件
我一直在尝试实现一个捕获所有异常的自定义插件,但我没有成功地让它工作。
在 插件/catch.js 中:
export default (ctx, inject) => {
const catchPlugin = function (func) {
return async function (args) {
try {
await func(args)
} catch (e) {
return console.error(e)
}
}
};
ctx.$catch = catchPlugin;
inject('catch', catchPlugin);
}
在 页面/login.vue 中:
export default {
methods: {
onLogin: this.$catch(async function () {
await this.$store.dispatch('auth/login', { email: this.email, password: this.password });
this.$router.push('/home');
}),
},
}
优点
- 没有样板。
- 插件中捕获的所有错误。
缺点
- 我无法让它工作。 :(
我的印象是 vue/nuxt 中缺少关于错误处理的文档。谁能得到第四种工作选择?这会是理想的吗?还有其他选择吗?什么是常规?
感谢您的时间!
原文由 nomadoda 发布,翻译遵循 CC BY-SA 4.0 许可协议
选项 #4 不起作用的原因是因为您要返回一个永远不会执行的函数:
用法:
如您所见,您还需要执行内部函数,以使您的示例工作:
但是…我相信处理组件中的错误并不是一件坏事,因为这与您的视图组件紧密耦合。例如,考虑一个登录组件,我们现在看到的是一个全局错误处理程序 (toastr),如果用户名/密码不正确,它会显示提示消息。根据我的经验,这不是最好的行为,它是一个很好的起点,但更好的做法是在组件附近添加错误消息,显示究竟出了什么问题。这意味着您将始终必须在组件本身中添加错误处理(与 UI 相关)。
我们公司的同事也在为同一产品工作而苦苦挣扎。一种是添加错误处理,另一种不是。在我看来,唯一的解决方案是教育开发人员始终添加正确的错误处理。
async/await
的语法还不错:关于您的最后一件事
con
: 未在 vuex 中处理和存储的错误。 .为什么这是一个骗局?您是否需要在全球范围内提供错误信息?我经常看到人们在vuex
中 放入了如此多的无用状态,这些状态仅用于组件本身。拥有本地组件状态也不错。既然是关于登录的,这个错误应该只有登录组件才知道。