🦄 refactor(store): setup 写法

(cherry picked from commit ada9ac3d88237e3c3ea9b0cbd8e070c33fe5b927)
This commit is contained in:
BTMuli
2023-04-06 16:22:03 +08:00
parent 0cdf2c80b9
commit 3001e40d4d
12 changed files with 229 additions and 247 deletions

View File

@@ -32,7 +32,7 @@ import TBackTop from "./components/t-backTop.vue";
// tauri // tauri
import { fs, window, app } from "@tauri-apps/api"; import { fs, window, app } from "@tauri-apps/api";
// store // store
import useAppStore from "./store/modules/app"; import { useAppStore } from "./store/modules/app";
// utils // utils
import { InitTGData, DeleteTGData, WriteTGData } from "./utils/TGIndex"; import { InitTGData, DeleteTGData, WriteTGData } from "./utils/TGIndex";
// data // data
@@ -53,7 +53,6 @@ onMounted(async () => {
}); });
async function checkLoad () { async function checkLoad () {
await appStore.check();
if (appStore.loading) { if (appStore.loading) {
console.info("数据已加载!"); console.info("数据已加载!");
return; return;
@@ -77,7 +76,7 @@ async function createDataDir () {
async function writeData () { async function writeData () {
console.info("开始写入数据..."); console.info("开始写入数据...");
TGAppDataList.map(async (item) => { TGAppDataList.map(async (item) => {
await fs.writeFile(`${appStore.dataPath.app}\\${item.name}`, JSON.stringify(item.data)); await fs.writeFile(`${appStore.dataPath.appDataDir}\\${item.name}`, JSON.stringify(item.data));
}); });
console.info("数据写入完成!"); console.info("数据写入完成!");
} }

View File

@@ -50,7 +50,7 @@
import { ref, onMounted } from "vue"; import { ref, onMounted } from "vue";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
// store // store
import useHomeStore from "../store/modules/home"; import { useHomeStore } from "../store/modules/home";
// utils // utils
import { createTGWindow } from "../utils/TGWindow"; import { createTGWindow } from "../utils/TGWindow";
// plugins // plugins

View File

@@ -111,7 +111,7 @@
// vue // vue
import { computed, ref } from "vue"; import { computed, ref } from "vue";
// store // store
import useAppStore from "../store/modules/app"; import { useAppStore } from "../store/modules/app";
const appStore = useAppStore(); const appStore = useAppStore();

View File

@@ -106,7 +106,7 @@ import TLoading from "../components/t-loading.vue";
// tauri // tauri
import { dialog, fs } from "@tauri-apps/api"; import { dialog, fs } from "@tauri-apps/api";
// Store // Store
import useAchievementsStore from "../store/modules/achievements"; import { useAchievementsStore } from "../store/modules/achievements";
// Interface // Interface
import { Achievements, UiafHeader, UiafAchievement } from "../plugins/UIAF/interface/UIAF"; import { Achievements, UiafHeader, UiafAchievement } from "../plugins/UIAF/interface/UIAF";
import { Achievement as TGAchievement, AchievementSeries as TGSeries } from "../interface/Achievements"; import { Achievement as TGAchievement, AchievementSeries as TGSeries } from "../interface/Achievements";
@@ -328,7 +328,7 @@ async function importJson () {
// 导出 // 导出
async function exportJson () { async function exportJson () {
// 判断是否有数据 // 判断是否有数据
if (achievementsStore.fin_achievements === 0) { if (achievementsStore.finAchievements === 0) {
snackbarText.value = "没有可导出的数据"; snackbarText.value = "没有可导出的数据";
snackbar.value = true; snackbar.value = true;
return; return;

View File

@@ -98,7 +98,7 @@ import GenshinOper from "../plugins/Genshin";
import { createTGWindow } from "../utils/TGWindow"; import { createTGWindow } from "../utils/TGWindow";
// interface // interface
import { AnnoListData, AnnoListCard } from "../plugins/Genshin/interface/announcement"; import { AnnoListData, AnnoListCard } from "../plugins/Genshin/interface/announcement";
import useAppStore from "../store/modules/app"; import { useAppStore } from "../store/modules/app";
// store // store
const appStore = useAppStore(); const appStore = useAppStore();

View File

@@ -23,8 +23,7 @@
<v-list-item-title> <v-list-item-title>
应用版本 应用版本
<v-btn <v-btn
class="card-btn" class="card-btn" size="small"
size="small"
@click="toOuter('https://github.com/BTMuli/Tauri.Genshin/releases/latest')" @click="toOuter('https://github.com/BTMuli/Tauri.Genshin/releases/latest')"
> >
Alpha Alpha
@@ -39,7 +38,7 @@
<img class="config-icon" src="../assets/icons/achievements.svg" alt="Achievements"> <img class="config-icon" src="../assets/icons/achievements.svg" alt="Achievements">
</template> </template>
<template #append> <template #append>
<v-list-item-subtitle>{{ achievementsStore.last_version }}</v-list-item-subtitle> <v-list-item-subtitle>{{ achievementsStore.lastVersion }}</v-list-item-subtitle>
</template> </template>
</v-list-item> </v-list-item>
<v-list-subheader inset class="config-header"> <v-list-subheader inset class="config-header">
@@ -80,10 +79,7 @@
</template> </template>
<template #append> <template #append>
<v-switch <v-switch
v-model="appStore.devMode" v-model="appStore.devMode" :label="appStore.devMode ? '开启' : '关闭'" inset color="#FAC51E"
:label="appStore.devMode ? '开启' : '关闭'"
inset
color="#FAC51E"
@click="submitDevMode" @click="submitDevMode"
/> />
</template> </template>
@@ -92,7 +88,7 @@
<template #prepend> <template #prepend>
<v-icon>mdi-view-dashboard</v-icon> <v-icon>mdi-view-dashboard</v-icon>
</template> </template>
<v-select v-model="showHome" :items="homeStore.getShowItem()" label="首页显示组件" multiple chips /> <v-select v-model="showHome" :items="homeStore.getShowItems()" label="首页显示组件" multiple chips />
<template #append> <template #append>
<v-btn class="card-btn" @click="submitHome"> <v-btn class="card-btn" @click="submitHome">
<template #prepend> <template #prepend>
@@ -108,11 +104,11 @@
<v-divider inset class="border-opacity-75" /> <v-divider inset class="border-opacity-75" />
<v-list-item prepend-icon="mdi-folder"> <v-list-item prepend-icon="mdi-folder">
<v-list-item-title>本地应用数据路径</v-list-item-title> <v-list-item-title>本地应用数据路径</v-list-item-title>
<v-list-item-subtitle>{{ appStore.dataPath.app }}</v-list-item-subtitle> <v-list-item-subtitle>{{ appStore.dataPath.appDataDir }}</v-list-item-subtitle>
</v-list-item> </v-list-item>
<v-list-item prepend-icon="mdi-folder"> <v-list-item prepend-icon="mdi-folder">
<v-list-item-title>本地用户数据路径</v-list-item-title> <v-list-item-title>本地用户数据路径</v-list-item-title>
<v-list-item-subtitle>{{ appStore.dataPath.user }}</v-list-item-subtitle> <v-list-item-subtitle>{{ appStore.dataPath.userDataDir }}</v-list-item-subtitle>
</v-list-item> </v-list-item>
</v-list> </v-list>
<!-- 弹窗提示条 --> <!-- 弹窗提示条 -->
@@ -132,9 +128,9 @@ import TConfirm from "../components/t-confirm.vue";
// tauri // tauri
import { dialog, fs, app, os } from "@tauri-apps/api"; import { dialog, fs, app, os } from "@tauri-apps/api";
// store // store
import useAppStore from "../store/modules/app"; import { useAppStore } from "../store/modules/app";
import useHomeStore from "../store/modules/home"; import { useHomeStore } from "../store/modules/home";
import useAchievementsStore from "../store/modules/achievements"; import { useAchievementsStore } from "../store/modules/achievements";
// utils // utils
import { WriteTGData } from "../utils/TGIndex"; import { WriteTGData } from "../utils/TGIndex";
// data // data
@@ -188,7 +184,7 @@ function toOuter (url: string) {
// 打开用户数据目录 // 打开用户数据目录
async function openMergeData () { async function openMergeData () {
await dialog.open({ await dialog.open({
defaultPath: appStore.dataPath.user, defaultPath: appStore.dataPath.userDataDir,
filters: [], filters: [],
}); });
} }
@@ -263,7 +259,6 @@ async function delUserData () {
// 恢复默认配置 // 恢复默认配置
async function initAppData () { async function initAppData () {
await appStore.init();
await homeStore.init(); await homeStore.init();
await achievementsStore.init(); await achievementsStore.init();
snackbarText.value = "已恢复默认配置!"; snackbarText.value = "已恢复默认配置!";

View File

@@ -11,7 +11,7 @@ import TPool from "../components/t-pool.vue";
import TPosition from "../components/t-position.vue"; import TPosition from "../components/t-position.vue";
import TCalendar from "../components/t-calendar.vue"; import TCalendar from "../components/t-calendar.vue";
// store // store
import useHomeStore from "../store/modules/home"; import { useHomeStore } from "../store/modules/home";
// store // store
const homeStore = useHomeStore(); const homeStore = useHomeStore();

View File

@@ -2,43 +2,53 @@
* @file store modules achievements.ts * @file store modules achievements.ts
* @description Achievements store module * @description Achievements store module
* @author BTMuli<bt-muli@outlook.com> * @author BTMuli<bt-muli@outlook.com>
* @since Alpha * @since Alpha v0.1.2
*/ */
// vue
import { ref } from "vue";
// pinia
import { defineStore } from "pinia"; import { defineStore } from "pinia";
const useAchievementsStore = defineStore({ export const useAchievementsStore = defineStore(
id: "achievements", "achievements", () => {
state () { // 成就数据
const totalAchievements = ref(899);
const finAchievements = ref(0);
const lastVersion = ref("v3.5");
const UIAFVersion = ref("v1.1");
const title = ref("成就完成数0/899 完成率0%");
function init (): void {
totalAchievements.value = 899;
finAchievements.value = 0;
title.value = getTitle();
}
function getTitle (): string {
return `成就完成数:${finAchievements.value}/${totalAchievements.value} 完成率:${(
(finAchievements.value / totalAchievements.value) *
100
).toFixed(2)}%`;
}
function flushData (total: number, fin: number): void {
totalAchievements.value = total;
finAchievements.value = fin;
title.value = getTitle();
}
return { return {
total_achievements: 899, totalAchievements,
fin_achievements: 0, finAchievements,
// 这个数据用于说明当前的数据版本,不会被渲染 lastVersion,
last_version: "v3.5", UIAFVersion,
UIAF_Version: "v1.1", title,
// 显示用,避免重复计算 init,
title: "成就完成数0/899 完成率0%", getTitle,
flushData,
}; };
}, },
actions: { {
init () { persist: true,
this.total_achievements = 899; });
this.fin_achievements = 0;
this.title = this.getTitle();
},
flushData (total: number, fin: number) {
this.total_achievements = total;
this.fin_achievements = fin;
this.title = this.getTitle();
},
getTitle () {
return `成就完成数:${this.fin_achievements}/${this.total_achievements} 完成率:${(
(this.fin_achievements / this.total_achievements) *
100
).toFixed(2)}%`;
},
},
persist: true,
});
export default useAchievementsStore;

View File

@@ -2,10 +2,14 @@
* @file store modules app.ts * @file store modules app.ts
* @description App store module * @description App store module
* @author BTMuli<bt-muli@outlook.com> * @author BTMuli<bt-muli@outlook.com>
* @since Alpha v0.1.1 * @since Alpha v0.1.2
*/ */
// vue
import { reactive, ref } from "vue";
// pinia
import { defineStore } from "pinia"; import { defineStore } from "pinia";
// tauri
import { path } from "@tauri-apps/api"; import { path } from "@tauri-apps/api";
// 用于存储原生数据的路径 // 用于存储原生数据的路径
@@ -15,108 +19,77 @@ const userDataDir = `${await path.appLocalDataDir()}userData`;
// 用于各种临时数据的路径 // 用于各种临时数据的路径
const tempDataDir = `${await path.appLocalDataDir()}tempData`; const tempDataDir = `${await path.appLocalDataDir()}tempData`;
const useAppStore = defineStore({ export const useAppStore = defineStore(
id: "app", "app",
state: () => { () => {
return { // 应用加载状态
// 是否加载数据 const loading = ref(false);
loading: false, // 侧边栏设置
// 侧边栏设置 const sidebar = reactive({
sidebar: { // 是否折叠
// 是否折叠 collapse: true,
collapse: true, // 是否显示
// 是否显示 submenu: {
submenu: { // 米游社
// 米游社 mihoyo: false,
mihoyo: false, // 数据库
// 数据库 database: false,
database: false,
},
},
// 开发者模式
devMode: false,
// 数据路径
dataPath: {
app: appDataDir,
user: userDataDir,
temp: tempDataDir,
},
// 应用数据路径
appPath: {
achievements: `${appDataDir}\\achievements.json`,
achievementSeries: `${appDataDir}\\achievementSeries.json`,
nameCards: `${appDataDir}\\nameCards.json`,
}, },
});
// 开发者模式
const devMode = ref(false);
const dataPath = reactive({
appDataDir,
userDataDir,
tempDataDir,
});
// 应用数据路径
const appPath = ref({
achievements: `${dataPath.appDataDir}/achievements.json`,
achievementSeries: `${dataPath.appDataDir}/achievementSeries.json`,
nameCards: `${dataPath.appDataDir}/nameCards.json`,
});
// 用户数据路径 // 用户数据路径
userPath: { const userPath = ref({
achievements: `${userDataDir}\\achievements.json`, achievements: `${dataPath.userDataDir}/achievements.json`,
}, });
function getSubmenu (): string[] {
const open = [];
if (sidebar.submenu.database) open.push("database");
if (sidebar.submenu.mihoyo) open.push("mihoyo");
return open;
}
return {
loading,
sidebar,
devMode,
dataPath,
appPath,
userPath,
getSubmenu,
}; };
}, },
actions: { {
// 检测 store 数据兼容,主要是 sideBar 数据 persist: [
async check () { {
if (this.sidebar === undefined) { key: "appPath",
this.sidebar = { storage: window.localStorage,
collapse: true, paths: ["dataPath", "appPath", "userPath"],
submenu: { },
mihoyo: false, {
database: false, key: "app",
}, storage: window.localStorage,
}; paths: ["devMode", "loading"],
} else { },
if (this.sidebar.collapse === undefined) this.sidebar.collapse = false; {
if (this.sidebar.submenu === undefined) { key: "sidebar",
this.sidebar.submenu = { database: false, mihoyo: false }; storage: window.localStorage,
} paths: ["sidebar"],
if (this.sidebar.submenu.database === undefined) this.sidebar.submenu.database = false; },
if (this.sidebar.submenu.mihoyo === undefined) this.sidebar.submenu.mihoyo = false; ],
}
},
// 初始化配置
async init () {
// 初始化侧边栏设置
this.sidebar = {
collapse: false,
submenu: {
mihoyo: false,
database: false,
},
};
// 初始化加载状态
this.loading = false;
// 初始化开发者模式
this.devMode = false;
// 初始化用户数据路径
this.userPath = {
achievements: `${userDataDir}\\achievements.json`,
};
},
// 获取折叠
getSubmenu () {
const open = [];
if (this.sidebar.submenu.database) open.push("database");
if (this.sidebar.submenu.mihoyo) open.push("mihoyo");
return open;
},
}, },
persist: [ );
{
key: "appPath",
storage: window.localStorage,
paths: ["dataPath", "appPath", "userPath"],
},
{
key: "app",
storage: window.localStorage,
paths: ["devMode", "loading"],
},
{
key: "sidebar",
storage: window.localStorage,
paths: ["sidebar"],
},
],
});
export default useAppStore;

View File

@@ -5,121 +5,126 @@
* @since Alpha v0.1.2 * @since Alpha v0.1.2
*/ */
// vue
import { ref } from "vue";
// pinia
import { defineStore } from "pinia"; import { defineStore } from "pinia";
// interface
import { type Map } from "../../interface/Base"; import { type Map } from "../../interface/Base";
const useHomeStore = defineStore({ export const useHomeStore = defineStore(
id: "home", "home", () => {
state: () => { const calendarShow = ref({
return { show: true,
calendar: { order: 3,
});
const poolShow = ref({
show: true,
order: 1,
});
const positionShow = ref({
show: true,
order: 2,
});
const hoemShow = ref({
calendarShow,
poolShow,
positionShow,
});
const poolCover = ref({} satisfies Map<string>);
function init (): void {
calendarShow.value = {
show: true, show: true,
order: 3, order: 3,
}, };
pool: { poolShow.value = {
show: true, show: true,
order: 1, order: 1,
}, };
position: { positionShow.value = {
show: true, show: true,
order: 2, order: 2,
},
poolCover: {} satisfies Map<string>,
};
},
actions: {
async init () {
this.$state = {
calendar: {
show: true,
order: 3,
},
pool: {
show: true,
order: 1,
},
position: {
show: true,
order: 2,
},
poolCover: {},
}; };
}, poolCover.value = {};
getShowItem () { }
function getShowItems (): string[] {
const defaultList = ["素材日历", "限时祈愿", "近期活动"]; const defaultList = ["素材日历", "限时祈愿", "近期活动"];
defaultList.sort((a, b) => { defaultList.sort((a, b) => {
return this.getItemOrder(a) - this.getItemOrder(b); return getItemOrder(a) - getItemOrder(b);
}); });
return defaultList; return defaultList;
}, }
getShowValue () {
function getShowValue (): string[] {
const showValue = []; const showValue = [];
if (this.calendar.show) showValue.push("素材日历"); if (calendarShow.value.show) showValue.push("素材日历");
if (this.pool.show) showValue.push("限时祈愿"); if (poolShow.value.show) showValue.push("限时祈愿");
if (this.position.show) showValue.push("近期活动"); if (positionShow.value.show) showValue.push("近期活动");
showValue.sort((a, b) => { showValue.sort((a, b) => {
return this.getItemOrder(a) - this.getItemOrder(b); return getItemOrder(a) - getItemOrder(b);
}); });
return showValue; return showValue;
}, }
getItemOrder (item: string) {
switch (item) { function getItemOrder (item: string): number {
case "素材日历": if (item === "素材日历") return calendarShow.value.order;
return this.calendar.order; if (item === "限时祈愿") return poolShow.value.order;
case "限时祈愿": if (item === "近期活动") return positionShow.value.order;
return this.pool.order; return 4;
case "近期活动": }
return this.position.order;
default: function setShowValue (value: string[]): void {
return 4;
}
},
setShowValue (value: string[]) {
let order = 1; let order = 1;
// 遍历 value // 遍历 value
value.forEach((item) => { value.forEach((item) => {
if (!this.getShowItem().includes(item)) { if (!getShowItems().includes(item)) {
throw new Error("传入的值不在可选范围内"); throw new Error("传入的值不在可选范围内");
} }
switch (item) { if (item === "素材日历") {
case "素材日历": calendarShow.value.order = order;
this.calendar.order = order; calendarShow.value.show = true;
this.calendar.show = true;
order++;
break;
case "限时祈愿":
this.pool.order = order;
this.pool.show = true;
order++;
break;
case "近期活动":
this.position.order = order;
this.position.show = true;
order++;
break;
default:
break;
}
// 没有显示的 item
if (!value.includes("素材日历")) {
this.calendar.show = false;
this.calendar.order = order;
order++; order++;
} }
if (!value.includes("限时祈愿")) { if (item === "限时祈愿") {
this.pool.show = false; poolShow.value.order = order;
this.pool.order = order; poolShow.value.show = true;
order++; order++;
} }
if (!value.includes("近期活动")) { if (item === "近期活动") {
this.position.show = false; positionShow.value.order = order;
this.position.order = order; positionShow.value.show = true;
order++; order++;
} }
}); });
}, // 遍历 getShowItems()
}, getShowItems().forEach((item) => {
persist: true, if (!value.includes(item)) {
}); if (item === "素材日历") {
calendarShow.value.show = false;
}
if (item === "限时祈愿") {
poolShow.value.show = false;
}
if (item === "近期活动") {
positionShow.value.show = false;
}
}
});
}
export default useHomeStore; return {
hoemShow,
poolCover,
init,
getShowItems,
getShowValue,
setShowValue,
};
}
,
{
persist: true,
},
);

View File

@@ -74,7 +74,7 @@ import TLoading from "../components/t-loading.vue";
// tauri // tauri
import { appWindow } from "@tauri-apps/api/window"; import { appWindow } from "@tauri-apps/api/window";
// store // store
import useAppStore from "../store/modules/app"; import { useAppStore } from "../store/modules/app";
// plugins // plugins
import MysOper from "../plugins/Mys"; import MysOper from "../plugins/Mys";
// interface // interface

View File

@@ -146,7 +146,7 @@ import { onMounted, ref } from "vue";
import { useRoute, useRouter } from "vue-router"; import { useRoute, useRouter } from "vue-router";
import TLoading from "../components/t-loading.vue"; import TLoading from "../components/t-loading.vue";
// store // store
import useAppStore from "../store/modules/app"; import { useAppStore } from "../store/modules/app";
// plugin // plugin
import MysOper from "../plugins/Mys"; import MysOper from "../plugins/Mys";
// utils // utils