Vuex-модуль-декоратор, изменяющий состояние внутри действия
С помощью 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: вы пытаетесь получить доступ к this.someMutation() или this.someGetter внутри @Action? Это работает только в динамических модулях. Если не динамическое, используйте this.context.commit("mutationName", payload) и 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
,
3 ответа
Просто добавьте опцию rawError в аннотацию, чтобы она стала
@Action({rawError: true})
И он нормально отображает ошибку. это связано с тем, что библиотека "vuex-module-decorators" оборачивает ошибку, поэтому, сделав это, вы сможете получить RawError, с которым можете работать
Вы можете проголосовать за этот ответ, если хотите, потому что он не отвечает на конкретный вопрос. Вместо этого я собираюсь предложить, чтобы, если вы используете машинописный текст, не используйте vuex. Я потратил последний месяц, пытаясь изучить vue / vuex и машинописный текст. Единственное, чему я привержен - это использование машинописного текста, потому что я твердо верю в преимущества использования машинописного текста. Я больше никогда не буду использовать необработанный javascript.
Если бы кто-то сказал мне не использовать vuex с самого начала, я бы спас себя 3 из последних 4 недель. Поэтому я здесь, чтобы попытаться поделиться этим пониманием с другими.
Ключ - это новая реализация ref в Vue 3. Это то, что действительно меняет правила игры для vuex и машинописного текста. Это позволяет нам не полагаться на vuex для автоматического переноса состояния в реактивное состояние. Вместо этого мы можем сделать это сами с помощью конструкции ref в vue 3. Вот небольшой пример из моего приложения, которое использует ref и класс машинописного текста, в котором я ожидал использовать vuex в прошлом.
ПРИМЕЧАНИЕ 1: единственное, что вы теряете при использовании этого подхода, - это инструменты vuex dev. ПРИМЕЧАНИЕ 2: я могу быть предвзятым, так как я перенес 25000 строк машинописного текста (с 7000 юнит-тестами) из Knockout.js в Vue. Knockout.js был посвящен предоставлению Observables (ссылка Vue) и привязке. Оглядываясь назад, я могу сказать, что это вроде как опережало свое время, но не получило поддержки и поддержки.
Хорошо, давайте создадим класс модуля vuex, который не использует vuex. Поместите это в appStore.ts. Для упрощения он будет просто включать информацию о пользователе и идентификатор клуба, в который он вошел. Пользователь может переключаться между клубами, поэтому для этого есть действие.
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();
}
или в компоненте на основе композиции Api. Это то, что заменит 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 может сам стать ссылкой. Но сначала я должен это проверить.
Я предлагаю это простое решение, оно отлично работает для меня:
// In SomeClassComponent.vue
import { getModule } from "vuex-module-decorators";
import YourModule from "@/store/YourModule";
someMethod() {
const moduleStore = getModule(YourModule, this.$store);
moduleStore.someAction();
}
Если у действия есть параметры, укажите их. Взято с: https://github.com/championswimmer/vuex-module-decorators/issues/86#issuecomment-464027359