Vue 3 / Pinia:如何正确处理错误,加载和数据



使用Fetch,而不是axios,我希望在组件中像这样接收数据:

const userStore = useAuthStore();
const { user, error, loading } = storeToRefs(userStore);
userStore.getMe();

但是我不知道怎么做。我想把错误,数据和加载状态直接放在一行,因为我觉得这样更好。

但是我不想在store中声明这样的加载:

export const useAuthStore = defineStore({
id: "auth",
state: () => ({
user: {} as User,
loading: false,
}),

因为如果我调用与这个store (User)相关的另一个方法,它将是相同的Loading状态。所以这个加载状态(甚至是错误状态)将会发生冲突。

如果我使用Javascript而不是Typescript,我肯定会替换掉这个。用户在获取或出错(在存储中)时这样做:

async getMe() {
this.user = { loading: true };
try {
return await AuthService.getMe();
} catch (error) {
if (error) {
his.user = { error };
}
}
},

因为它是TypeScript,所以我不能替换"user">

所有我想要的,是返回一个数据,错误,加载相关的唯一的动作(不相关的状态)。

身份验证存储:

import { defineStore } from "pinia";
import AuthService from "@/api/modules/auth";
interface User {
email: string;
first_name: string;
last_name: string;
force_password_change: boolean;
groups: string[];
has_2fa_enabled: boolean;
is_staff: boolean;
lang: string;
last_password_change: string;
permissions: string[];
session_expiry_date: string;
uid: string;
}
export const useAuthStore = defineStore({
id: "auth",
state: () => ({
user: {} as User,
loading: false,
}),
actions: {
async getMe() {
// this.user = { loading: true };
try {
return await AuthService.getMe();
} catch (error) {
if (error) {
// this.user = { error };
}
}
},
},
});

服务:

import { Api } from "../apiSettings";
class AuthService {
async getMe(): Promise<any> {
return await Api.get("api/auth/me/");
}
}
export default new AuthService();

App.vue:

<script setup lang="ts">
import { useAuthStore } from "@/stores";
import { storeToRefs } from "pinia";
const userStore = useAuthStore();
const { user } = storeToRefs(userStore);
userStore.getMe();
console.log(user.value);
</script>

您可以为加载和错误状态定义一个单独的对象,并将其与实际数据一起从存储的操作中返回。然后,您可以使用对象解构来提取组件中的加载、错误和数据状态。下面是一个例子:

身份验证存储:

import { defineStore } from "pinia";
import AuthService from "@/api/modules/auth";
interface RequestState {
loading: boolean;
error: Error | null;
}
export const useAuthStore = defineStore({
id: "auth",
state: () => ({
user: {} as User,
}),
actions: {
async getMe(): Promise<{ data: User; requestState: RequestState }> {
const requestState: RequestState = {
loading: true,
error: null,
};
try {
const data = await AuthService.getMe();
requestState.loading = false;
return { data, requestState };
} catch (error) {
requestState.loading = false;
requestState.error = error;
return { data: {} as User, requestState };
}
},
},
});

组件:

<script setup lang="ts">
import { useAuthStore } from "@/stores";
import { storeToRefs } from "pinia";
const userStore = useAuthStore();
const { user, requestState } = storeToRefs(userStore);
// Call the action to get user data
userStore.getMe();
console.log(user.value); // {} - initial value of user
console.log(requestState.value); // { loading: true, error: null }
// Use object destructuring to get the actual user data, loading and error         states
const { data, loading, error } = requestState.value;
if (loading) {
// Render a loading state
} else if (error) {
// Render an error state
} else {
// Render the user data
console.log(data);
}
</script>

最新更新