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

分享于2023年02月22日 pinia vue.js vuejs3 问答
【问题标题】:Vue 3 / Pinia: how to handle error, loading and data properlyVue 3 / Pinia:如何正确处理错误、加载和数据
【发布时间】:2023-02-14 11:39:13
【问题描述】:

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

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

userStore.getMe();

但我不知道该怎么做。 我希望在一行中直接显示错误、数据和加载状态,因为我认为这样更好。

但我不想在商店中声明这样的加载:

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

因为如果我调用另外一个和这个store相关的方法(User),也是一样的Loading状态。所以这个loading状态(甚至是error状态)都会有冲突。

如果我使用 Javascript 而不使用 Typescript,我肯定会在获取或出错时(在商店中)像这样替换 this.user :

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

因为它是 TypeScript,所以我无法像设置接口那样替换“用户”状态。

我想要的只是返回与唯一操作相关的数据、错误、加载(与状态无关)。

授权商店:

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 {
    return await Api.get("api/auth/me/");
  }
}

export default new AuthService();

应用程序.vue:



【解决方案1】:

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

授权商店:

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 };
      }
    },
  },
});

成分:


【讨论】: