使用 vuex-module-decorator ,我有一个authenticate
动作可以改变状态。
@Action
public authenticate(email: string, password: string): Promise<Principal> {
this.principal = null;
return authenticator
.authenticate(email, password)
.then(auth => {
const principal = new Principal(auth.username);
this.context.commit('setPrincipal', principal);
return principal;
})
.catch(error => {
this.context.commit('setError', error);
return error;
});
}
// mutations for error and principal
但是失败,并显示以下消息:
未处理的承诺拒绝错误:“ ERR_ACTION_ACCESS_UNDEFINED:您是否正在尝试在@Action中访问this.someMutation()或this.someGetter? 这仅在动态模块中有效。 如果不是动态的,请使用this.context.commit(“ mutationName”,有效负载)和this.context.getters [“ getterName”]
我不了解的是,它可以与@MutationAction
和async
配合使用。但是我错过了返回类型Promise<Principal>
。
@MutationAction
public async authenticate(email: string, password: string) {
this.principal = null;
try {
const auth = await authenticator.authenticate(email, password);
return { principal: new Principal(auth.username), error: null };
} catch (ex) {
const error = ex as Error;
return { principal: null, error };
}
}
-
这时候我感到受阻,希望获得一些帮助来实现一个@Action
,它可以改变状态并在Promise
中返回特定类型。
答案 0 :(得分:5)
只需在标记中添加rawError选项,使其变为
@Action({rawError: true})
它正常显示错误。这是因为库“ vuex-module-decorators”包装了错误,因此通过执行此操作,您将获得可以使用的RawError
答案 1 :(得分:3)
如果您愿意,可以拒绝该答案,因为它不能回答提出的特定问题。相反,我建议您使用打字稿,而不要使用vuex。在过去的一个月中,我一直在尝试学习vue / vuex和打字稿。我致力于使用打字稿,因为我坚信使用打字稿的好处。我将永远不会再使用原始javascript。
如果有人从一开始就告诉我不要使用vuex,那么我将在过去4周中为自己节省3个。因此,我在这里尝试与他人分享这种见解。
关键是Vue 3的新ref实现。真正改变了vuex和Typescript游戏的是什么。它使我们不必依靠vuex来自动将状态包装为反应式。相反,我们可以使用vue 3中的ref构造自己完成操作。这是我的应用程序中的一个小示例,该示例使用ref和一个typescript类,我曾期望在其中使用vuex。
注意1:使用这种方法时,您失去的一件事就是vuex开发工具。 注意2:我可能会因将25,000行的打字稿(带有7000个单元测试)从Knockout.js移植到Vue而产生偏差。 Knockout.js的全部目的是提供Observables(Vue的参考)和绑定。往回看,虽然有点超前,但没有得到支持和支持。
好吧,让我们创建一个不使用vuex的vuex模块类。将其放在appStore.ts中。为简化起见,它将仅包含用户信息和用户登录俱乐部的ID。用户可以切换球杆,因此需要执行操作。
export class AppClass {
public loaded: Ref<boolean>;
public userId: Ref<number>;
public userFirstName: Ref<string>;
public userLastName: Ref<string>;
// Getters are computed if you want to use them in components
public userName: Ref<string>;
constructor() {
this.loaded = ref(false);
initializeFromServer()
.then(info: SomeTypeWithSettingsFromServer) => {
this.userId = ref(info.userId);
this.userFirstName = ref(info.userFirstName);
this.userLastName = ref(info.userLastName);
this.userName = computed<string>(() =>
return this.userFirstName.value + ' ' + this.userLastName.value;
}
}
.catch(/* do some error handling here */);
}
private initializeFromServer(): Promise<SomeTypeWithSettingsFromServer> {
return axios.get('url').then((response) => response.data);
}
// This is a getter that you don't need to be reactive
public fullName(): string {
return this.userFirstName.value + ' ' + this.userLastName.value;
}
public switchToClub(clubId: number): Promise<any> {
return axios.post('switch url')
.then((data: clubInfo) => {
// do some processing here
}
.catch(// do some error handling here);
}
}
export appModule = new AppClass();
然后,当您想在任何地方访问appModule时,最终都会这样做:
import { appModule } from 'AppStore';
...
if (appModule.loaded.value) {
const userName = appModule.fullName();
}
或基于compositionApi的组件中。这将取代mapActions等。
<script lang="ts">
import { defineComponent } from '@vue/composition-api';
import { appModule } from '@/store/appStore';
import footer from './footer/footer.vue';
export default defineComponent({
name: 'App',
components: { sfooter: footer },
props: {},
setup() {
return { ...appModule }
}
});
</script>
现在您可以在模板中使用userId,userFirstName,userName等。
希望有帮助。
我刚刚添加了计算的吸气剂。我需要测试是否真的需要。可能不需要它,因为您可以只在模板中引用fullName(),并且因为fullName()引用了其他引用的.value变量,因此fullName本身可能会成为引用。但是我必须先检查一下。