vue3 pinia 多个stores文件能不能合并?

vue3 pinia
好几个文件里面代码很多都是一样的,有没有什么办法可以写一个就可以了。

下面两个 storesDTO 里面和 apiList 里面的请求的 api 不一样,怎样可以不用写很多个,而不影响

// userOptions.js

import {computed, ref} from 'vue'
import {defineStore} from 'pinia'
import {listRole} from "@/apis/role";
import {cardActionReload, notyError} from "@/utils";
import {useEventOptionsStore} from "@/stores/eventOptions";

export const useRoleOptionsStore = defineStore('roleOptions', () => {

    const eventOptions = useEventOptionsStore();

    const cardEvent = ref()

    const disabled = ref(false)

    const list = ref([]);

    const count = ref(0);

    const page_size_list = ref([5, 10, 20, 50, 100])

    const total_page = computed(() => {
        if (count.value === 0 || DTO.value.page_size >= count.value) {
            return 1;
        } else {
            return (count.value % DTO.value.page_size === 0) ? (count.value / DTO.value.page_size) : Math.ceil(count.value / DTO.value.page_size);
        }
    })

    const page_list = computed(() => {
        let arr = [];

        if (total_page.value <= 7) {
            for (let i = 0; i < (total_page.value - 1); i++) {
                arr.push(i + 2);
            }
        } else {
            if (DTO.value.page >= 5) {
                if (total_page.value - DTO.value.page < 2) {
                    arr = [total_page.value - 4, total_page.value - 3, total_page.value - 2, total_page.value - 1, total_page.value];
                } else {
                    arr = [DTO.value.page - 2, DTO.value.page - 1, DTO.value.page, DTO.value.page + 1, DTO.value.page + 2];
                }
            } else {
                arr = [2, 3, 4, 5, 6, 7];
            }
        }

        return arr;
    })

    const editPage = async (page) => {
        DTO.value.has_count = false;
        DTO.value.page = parseInt(page);

        await apiList();
    }

    const editPageSize = async (page_size) => {
        if (page_size) {
            DTO.value.page_size = parseInt(page_size);
        }
        DTO.value.has_count = false;
        DTO.value.page = 1;

        await apiList();
    }

    const DTO = ref({
        role: '',
        page: 1,
        page_size: 20
    });

    const apiList = async () => {
        const reload = cardActionReload(cardEvent.value);
        reload.open();

        const {code, msg, data} = await listRole(DTO.value);
        if (code === 0 && data) {
            list.value = data.list;

            count.value = data.count;
        } else {
            notyError(msg);
        }

        reload.close();

        eventOptions.classContentInnerEvent?.scrollTo(0, 0);
    }

    return {cardEvent, disabled, list, count, page_size_list, total_page, page_list, editPage, editPageSize, DTO, apiList}
})
// userOptions.js

import {computed, ref} from 'vue'
import {defineStore} from 'pinia'
import {listUser} from "@/apis/user";
import {cardActionReload, notyError} from "@/utils";
import {useEventOptionsStore} from "@/stores/eventOptions";

export const useUserOptionsStore = defineStore('userOptions', () => {

    const eventOptions = useEventOptionsStore();

    const cardEvent = ref()

    const disabled = ref(false)

    const list = ref([]);

    const count = ref(0);

    const page_size_list = ref([5, 10, 20, 50, 100])

    const total_page = computed(() => {
        if (count.value === 0 || DTO.value.page_size >= count.value) {
            return 1;
        } else {
            return (count.value % DTO.value.page_size === 0) ? (count.value / DTO.value.page_size) : Math.ceil(count.value / DTO.value.page_size);
        }
    })

    const page_list = computed(() => {
        let arr = [];

        if (total_page.value <= 7) {
            for (let i = 0; i < (total_page.value - 1); i++) {
                arr.push(i + 2);
            }
        } else {
            if (DTO.value.page >= 5) {
                if (total_page.value - DTO.value.page < 2) {
                    arr = [total_page.value - 4, total_page.value - 3, total_page.value - 2, total_page.value - 1, total_page.value];
                } else {
                    arr = [DTO.value.page - 2, DTO.value.page - 1, DTO.value.page, DTO.value.page + 1, DTO.value.page + 2];
                }
            } else {
                arr = [2, 3, 4, 5, 6, 7];
            }
        }

        return arr;
    })

    const editPage = async (page) => {
        DTO.value.has_count = false;
        DTO.value.page = parseInt(page);

        await apiList();
    }

    const editPageSize = async (page_size) => {
        if (page_size) {
            DTO.value.page_size = parseInt(page_size);
        }
        DTO.value.has_count = false;
        DTO.value.page = 1;

        await apiList();
    }

    const DTO = ref({
        user_id: '',
        page: 1,
        page_size: 20
    });

    const apiList = async () => {
        const reload = cardActionReload(cardEvent.value);
        reload.open();

        const {code, msg, data} = await listUser(DTO.value);
        if (code === 0 && data) {
            list.value = data.list;

            count.value = data.count;
        } else {
            notyError(msg);
        }

        reload.close();

        eventOptions.classContentInnerEvent?.scrollTo(0, 0);
    }

    return {cardEvent, disabled, list, count, page_size_list, total_page, page_list, editPage, editPageSize, DTO, apiList}
})
阅读 1k
avatarAI BotBETA

要合并多个 Vue 3 Pinia store 文件,你可以考虑创建一个通用的 store 结构,并使用函数参数或高阶函数来定制每个 store 的特定部分。以下是一个简化的示例,展示如何做到这一点:

首先,创建一个通用的 store 工厂函数:

import { computed, ref } from 'vue';
import { defineStore } from 'pinia';

// 通用的 store 工厂函数
export function createPaginatedStore(apiFunction, storeId, dtoDefaults) {
  return defineStore(storeId, () => {
    const cardEvent = ref();
    const disabled = ref(false);
    const list = ref([]);
    const count = ref(0);
    const page_size_list = ref([5, 10, 20, 50, 100]);
    const DTO = ref(dtoDefaults);

    const total_page = computed(() => {
      if (count.value === 0 || DTO.value.page_size >= count.value) {
        return 1;
      } else {
        return Math.ceil(count.value / DTO.value.page_size);
      }
    });

    const page_list = computed(() => {
      let arr = [];

      if (total_page.value <= 7) {
        for (let i = 0; i < (total_page.value - 1); i++) {
          arr.push(i + 2);
        }
      } else {
        if (DTO.value.page >= 5) {
          if (total_page.value - DTO.value.page < 2) {
            arr = [total_page.value - 4, total_page.value - 3, total_page.value - 2, total_page.value - 1, total_page.value];
          } else {
            arr = [DTO.value.page - 2, DTO.value.page - 1, DTO.value.page, DTO.value.page + 1, DTO.value.page + 2];
          }
        } else {
          arr = [2, 3, 4, 5, 6, 7];
        }
      }

      return arr;
    });

    const editPage = async (page) => {
      DTO.value.page = parseInt(page);
      await fetchData();
    };

    const editPageSize = async (page_size) => {
      if (page_size) {
        DTO.value.page_size = parseInt(page_size);
      }
      DTO.value.page = 1;
      await fetchData();
    };

    const fetchData = async () => {
      const reload = cardActionReload(cardEvent.value);
      reload.open();

      try {
        const { code, msg, data } = await apiFunction(DTO.value);
        if (code === 0 && data) {
          list.value = data.list;
          count.value = data.count;
        } else {
          notyError(msg);
        }
      } finally {
        reload.close();
      }
    };

    // 初始化数据加载
    fetchData();

    return {
      cardEvent,
      disabled,
      list,
      count,
      page_size_list,
      total_page,
      page_list,
      editPage,
      editPageSize,
      DTO
    };
  });
}

然后,你可以使用这个工厂函数来创建多个 store,每个 store 都有自己的 API 函数和 DTO 默认值:

// userOptions.js
import { createPaginatedStore } from './paginatedStoreFactory';
import { listRole } from "@/apis/role";
import { cardActionReload, notyError } from "@/utils";
import { useEventOptionsStore } from "@/stores/eventOptions";

export const useRoleOptionsStore = createPaginatedStore(
  listRole,
  'roleOptions',
  { role: '', page: 1, page_size: 20 }
);

// userOptions.js
import { createPaginatedStore } from './paginatedStoreFactory';
import { listUser } from "@/apis/user";
import { cardActionReload, notyError } from "@/utils";
import { useEventOptionsStore } from "@/stores/eventOptions";
1 个回答

很多函数都可以提取成单个JS文件哇,然后再在对应的 Store 文件里面 import 使用就可以了。


最后插一嘴,就是为啥要把分页请求之类的操作放到 Pinia 里面呢?

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题