🦄 refactor: 重构代码将 Vuex替换为 Pinia

集成 Pinia 状态管理
This commit is contained in:
alger
2025-03-19 22:48:28 +08:00
parent 4fa5ed0ca6
commit e355341596
40 changed files with 1170 additions and 494 deletions
+30 -24
View File
@@ -16,7 +16,7 @@
<n-dropdown trigger="hover" :options="searchTypeOptions" @select="selectSearchType">
<div class="w-20 px-3 flex justify-between items-center">
<div>
{{ searchTypeOptions.find((item) => item.key === store.state.searchType)?.label }}
{{ searchTypeOptions.find((item) => item.key === searchStore.searchType)?.label }}
</div>
<i class="iconfont icon-xiasanjiaoxing"></i>
</div>
@@ -28,11 +28,11 @@
<template #trigger>
<div class="user-box">
<n-avatar
v-if="store.state.user"
v-if="userStore.user"
class="cursor-pointer"
circle
size="medium"
:src="getImgUrl(store.state.user.avatarUrl)"
:src="getImgUrl(userStore.user.avatarUrl)"
@click="selectItem('user')"
/>
<div v-else class="mx-2 rounded-full cursor-pointer text-sm" @click="toLogin">
@@ -41,16 +41,16 @@
</div>
</template>
<div class="user-popover">
<div v-if="store.state.user" class="user-header" @click="selectItem('user')">
<n-avatar circle size="small" :src="getImgUrl(store.state.user?.avatarUrl)" />
<span class="username">{{ store.state.user?.nickname || 'Theodore' }}</span>
<div v-if="userStore.user" class="user-header" @click="selectItem('user')">
<n-avatar circle size="small" :src="getImgUrl(userStore.user?.avatarUrl)" />
<span class="username">{{ userStore.user?.nickname || 'Theodore' }}</span>
</div>
<div class="menu-items">
<div v-if="!store.state.user" class="menu-item" @click="toLogin">
<div v-if="!userStore.user" class="menu-item" @click="toLogin">
<i class="iconfont ri-login-box-line"></i>
<span>{{ t('comp.searchBar.toLogin') }}</span>
</div>
<div v-if="store.state.user" class="menu-item" @click="selectItem('logout')">
<div v-if="userStore.user" class="menu-item" @click="selectItem('logout')">
<i class="iconfont ri-logout-box-r-line"></i>
<span>{{ t('comp.searchBar.logout') }}</span>
</div>
@@ -60,9 +60,9 @@
<span>{{ t('comp.searchBar.set') }}</span>
</div>
<div class="menu-item">
<i class="iconfont" :class="isDarkTheme ? 'ri-moon-line' : 'ri-sun-line'"></i>
<i class="iconfont" :class="isDark ? 'ri-moon-line' : 'ri-sun-line'"></i>
<span>{{ t('comp.searchBar.theme') }}</span>
<n-switch v-model:value="isDarkTheme" class="ml-auto">
<n-switch v-model:value="isDark" class="ml-auto">
<template #checked>
<i class="ri-moon-line"></i>
</template>
@@ -105,7 +105,6 @@
import { computed, onMounted, ref, watchEffect } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router';
import { useStore } from 'vuex';
import { getSearchKeyword } from '@/api/home';
import { getUserDetail } from '@/api/login';
@@ -113,13 +112,20 @@ import alipay from '@/assets/alipay.png';
import wechat from '@/assets/wechat.png';
import Coffee from '@/components/Coffee.vue';
import { SEARCH_TYPES, USER_SET_OPTIONS } from '@/const/bar-const';
import { usePlayerStore } from '@/store/modules/player';
import { useSearchStore } from '@/store/modules/search';
import { useSettingsStore } from '@/store/modules/settings';
import { useUserStore } from '@/store/modules/user';
import { getImgUrl } from '@/utils';
import { checkUpdate, UpdateResult } from '@/utils/update';
import config from '../../../../package.json';
const router = useRouter();
const store = useStore();
const playerStore = usePlayerStore();
const searchStore = useSearchStore();
const settingsStore = useSettingsStore();
const userStore = useUserStore();
const userSetOptions = ref(USER_SET_OPTIONS);
const { t } = useI18n();
@@ -137,15 +143,15 @@ const loadPage = async () => {
if (!token) return;
const { data } = await getUserDetail();
console.log('data', data);
store.state.user =
data.profile || store.state.user || JSON.parse(localStorage.getItem('user') || '{}');
localStorage.setItem('user', JSON.stringify(store.state.user));
userStore.user =
data.profile || userStore.user || JSON.parse(localStorage.getItem('user') || '{}');
localStorage.setItem('user', JSON.stringify(userStore.user));
};
loadPage();
watchEffect(() => {
if (store.state.user) {
if (userStore.user) {
userSetOptions.value = USER_SET_OPTIONS;
} else {
userSetOptions.value = USER_SET_OPTIONS.filter((item) => item.key !== 'logout');
@@ -167,9 +173,9 @@ onMounted(() => {
checkForUpdates();
});
const isDarkTheme = computed({
get: () => store.state.theme === 'dark',
set: () => store.commit('toggleTheme')
const isDark = computed({
get: () => settingsStore.theme === 'dark',
set: () => settingsStore.toggleTheme()
});
// 搜索词
@@ -182,7 +188,7 @@ const search = () => {
}
if (router.currentRoute.value.path === '/search') {
store.state.searchValue = value;
searchStore.searchValue = value;
return;
}
@@ -190,13 +196,13 @@ const search = () => {
path: '/search',
query: {
keyword: value,
type: store.state.searchType
type: searchStore.searchType
}
});
};
const selectSearchType = (key: number) => {
store.state.searchType = key;
searchStore.searchType = key;
if (searchValue.value) {
search();
}
@@ -208,7 +214,7 @@ const selectItem = async (key: string) => {
// switch 判断
switch (key) {
case 'logout':
store.commit('logout');
userStore.handleLogout();
break;
case 'login':
router.push('/login');
@@ -250,7 +256,7 @@ const checkForUpdates = async () => {
const toGithubRelease = () => {
if (updateInfo.value.hasUpdate) {
store.commit('setShowUpdateModal', true);
settingsStore.showUpdateModal = true;
} else {
window.open('https://github.com/algerkong/AlgerMusicPlayer/releases', '_blank');
}