This commit is contained in:
2026-06-24 10:04:03 +08:00
parent b103192fac
commit 0f961789dc
538 changed files with 128210 additions and 128008 deletions
+196 -196
View File
@@ -1,197 +1,197 @@
import { defineStore } from 'pinia';
import { ref, computed, reactive } from 'vue';
// ========== 全局状态 Store ==========
function initState() {
return {
isCollapse: false,
};
}
export const useAllDataStore = defineStore('allData', () => {
const state = reactive(initState());
const count = ref(0);
const doubleCount = computed(() => count.value * 2);
function increment() {
count.value++;
}
return {
state,
count,
doubleCount,
increment,
};
});
// ========== 多标签页 Tabs Store ==========
import { defineStore as defineTabsStore } from 'pinia';
import { ref as vueRef } from 'vue';
/**
* 多标签页Tabs状态管理
* tabList每个tab结构: {
* title: 标签显示名,
* fullPath: 路由路径(唯一key),
* name: 路由name,
* icon: 图标(可选)
* }
*/
export const useTabsStore = defineTabsStore('tabs', () => {
// 固定首页tab
const defaultDashboardPath = '/home';
// 从 localStorage 恢复 tabs 状态
function loadTabsFromStorage() {
try {
const savedTabs = localStorage.getItem('tabs_list');
const savedActiveTab = localStorage.getItem('active_tab');
if (savedTabs) {
const tabs = JSON.parse(savedTabs);
// 确保至少包含首页
const hasHome = tabs.some(t => t.fullPath === defaultDashboardPath);
if (!hasHome) {
tabs.unshift({ title: '首页', fullPath: defaultDashboardPath, name: 'Home' });
}
return tabs;
}
} catch (e) {
console.warn('恢复 tabs 失败:', e);
}
return [{ title: '首页', fullPath: defaultDashboardPath, name: 'Home' }];
}
// 保存 tabs 到 localStorage
function saveTabsToStorage(tabs, active) {
try {
localStorage.setItem('tabs_list', JSON.stringify(tabs));
if (active) {
localStorage.setItem('active_tab', active);
}
} catch (e) {
console.warn('保存 tabs 失败:', e);
}
}
const tabList = vueRef(loadTabsFromStorage());
const savedActiveTab = localStorage.getItem('active_tab');
const activeTab = vueRef(savedActiveTab || defaultDashboardPath);
// 添加tab,若已存在则激活
function addTab(tab) {
const exist = tabList.value.find((t) => t.fullPath === tab.fullPath);
if (!exist) {
tabList.value.push(tab);
}
activeTab.value = tab.fullPath;
saveTabsToStorage(tabList.value, activeTab.value);
}
// 删除指定tab并切换激活tab
function removeTab(fullPath) {
const idx = tabList.value.findIndex((t) => t.fullPath === fullPath);
if (idx > -1) {
tabList.value.splice(idx, 1);
// 只在关闭当前激活tab时切换激活tab
if (activeTab.value === fullPath) {
if (tabList.value.length > 0) {
// 优先激活右侧(如无则激活左侧)
const newIdx = idx >= tabList.value.length ? tabList.value.length - 1 : idx;
activeTab.value = tabList.value[newIdx].fullPath;
} else {
// 全部关闭,兜底首页
activeTab.value = defaultDashboardPath;
}
}
saveTabsToStorage(tabList.value, activeTab.value);
}
}
// 关闭其他,只留首页和当前激活tab
function closeOthers() {
tabList.value = tabList.value.filter(
(t) => t.fullPath === defaultDashboardPath || t.fullPath === activeTab.value
);
saveTabsToStorage(tabList.value, activeTab.value);
}
// 关闭左侧(关闭指定tab左侧的所有tab,保留首页和目标tab)
function closeLeft(targetFullPath) {
const targetIndex = tabList.value.findIndex((t) => t.fullPath === targetFullPath);
if (targetIndex > -1) {
// 保留首页和目标tab及其右侧的所有tab
const beforeIndex = tabList.value.slice(0, targetIndex);
const hasCloseableLeft = beforeIndex.some(t => t.fullPath !== defaultDashboardPath);
if (hasCloseableLeft) {
tabList.value = tabList.value.filter((t, index) =>
t.fullPath === defaultDashboardPath || index >= targetIndex
);
// 如果关闭的tab中包含了当前激活的tab,则激活目标tab
if (!tabList.value.find(t => t.fullPath === activeTab.value)) {
activeTab.value = targetFullPath;
}
saveTabsToStorage(tabList.value, activeTab.value);
}
}
}
// 关闭右侧(关闭指定tab右侧的所有tab,保留首页和目标tab)
function closeRight(targetFullPath) {
const targetIndex = tabList.value.findIndex((t) => t.fullPath === targetFullPath);
if (targetIndex > -1) {
// 保留首页和目标tab及其左侧的所有tab
const afterIndex = tabList.value.slice(targetIndex + 1);
const hasCloseableRight = afterIndex.length > 0;
if (hasCloseableRight) {
tabList.value = tabList.value.filter((t, index) =>
t.fullPath === defaultDashboardPath || index <= targetIndex
);
// 如果关闭的tab中包含了当前激活的tab,则激活目标tab
if (!tabList.value.find(t => t.fullPath === activeTab.value)) {
activeTab.value = targetFullPath;
}
saveTabsToStorage(tabList.value, activeTab.value);
}
}
}
// 关闭全部,只留首页
function closeAll() {
tabList.value = tabList.value.filter((t) => t.fullPath === defaultDashboardPath);
activeTab.value = defaultDashboardPath;
saveTabsToStorage(tabList.value, activeTab.value);
}
// 设置激活tab(不触发路由跳转,仅用于更新状态)
function setActiveTab(fullPath) {
activeTab.value = fullPath;
saveTabsToStorage(tabList.value, activeTab.value);
}
// 重置 tabs store 到初始状态(登出时使用)
function resetTabs() {
tabList.value = [{ title: '首页', fullPath: defaultDashboardPath, name: 'Dashboard' }];
activeTab.value = defaultDashboardPath;
// 清除 localStorage 中的 tabs 数据
localStorage.removeItem('tabs_list');
localStorage.removeItem('active_tab');
}
return {
tabList,
activeTab,
addTab,
removeTab,
closeOthers,
closeLeft,
closeRight,
closeAll,
setActiveTab,
saveTabsToStorage,
resetTabs,
};
});
// ========== 菜单 Menu Store ==========
import { defineStore } from 'pinia';
import { ref, computed, reactive } from 'vue';
// ========== 全局状态 Store ==========
function initState() {
return {
isCollapse: false,
};
}
export const useAllDataStore = defineStore('allData', () => {
const state = reactive(initState());
const count = ref(0);
const doubleCount = computed(() => count.value * 2);
function increment() {
count.value++;
}
return {
state,
count,
doubleCount,
increment,
};
});
// ========== 多标签页 Tabs Store ==========
import { defineStore as defineTabsStore } from 'pinia';
import { ref as vueRef } from 'vue';
/**
* 多标签页Tabs状态管理
* tabList每个tab结构: {
* title: 标签显示名,
* fullPath: 路由路径(唯一key),
* name: 路由name,
* icon: 图标(可选)
* }
*/
export const useTabsStore = defineTabsStore('tabs', () => {
// 固定首页tab
const defaultDashboardPath = '/home';
// 从 localStorage 恢复 tabs 状态
function loadTabsFromStorage() {
try {
const savedTabs = localStorage.getItem('tabs_list');
const savedActiveTab = localStorage.getItem('active_tab');
if (savedTabs) {
const tabs = JSON.parse(savedTabs);
// 确保至少包含首页
const hasHome = tabs.some(t => t.fullPath === defaultDashboardPath);
if (!hasHome) {
tabs.unshift({ title: '首页', fullPath: defaultDashboardPath, name: 'Home' });
}
return tabs;
}
} catch (e) {
console.warn('恢复 tabs 失败:', e);
}
return [{ title: '首页', fullPath: defaultDashboardPath, name: 'Home' }];
}
// 保存 tabs 到 localStorage
function saveTabsToStorage(tabs, active) {
try {
localStorage.setItem('tabs_list', JSON.stringify(tabs));
if (active) {
localStorage.setItem('active_tab', active);
}
} catch (e) {
console.warn('保存 tabs 失败:', e);
}
}
const tabList = vueRef(loadTabsFromStorage());
const savedActiveTab = localStorage.getItem('active_tab');
const activeTab = vueRef(savedActiveTab || defaultDashboardPath);
// 添加tab,若已存在则激活
function addTab(tab) {
const exist = tabList.value.find((t) => t.fullPath === tab.fullPath);
if (!exist) {
tabList.value.push(tab);
}
activeTab.value = tab.fullPath;
saveTabsToStorage(tabList.value, activeTab.value);
}
// 删除指定tab并切换激活tab
function removeTab(fullPath) {
const idx = tabList.value.findIndex((t) => t.fullPath === fullPath);
if (idx > -1) {
tabList.value.splice(idx, 1);
// 只在关闭当前激活tab时切换激活tab
if (activeTab.value === fullPath) {
if (tabList.value.length > 0) {
// 优先激活右侧(如无则激活左侧)
const newIdx = idx >= tabList.value.length ? tabList.value.length - 1 : idx;
activeTab.value = tabList.value[newIdx].fullPath;
} else {
// 全部关闭,兜底首页
activeTab.value = defaultDashboardPath;
}
}
saveTabsToStorage(tabList.value, activeTab.value);
}
}
// 关闭其他,只留首页和当前激活tab
function closeOthers() {
tabList.value = tabList.value.filter(
(t) => t.fullPath === defaultDashboardPath || t.fullPath === activeTab.value
);
saveTabsToStorage(tabList.value, activeTab.value);
}
// 关闭左侧(关闭指定tab左侧的所有tab,保留首页和目标tab)
function closeLeft(targetFullPath) {
const targetIndex = tabList.value.findIndex((t) => t.fullPath === targetFullPath);
if (targetIndex > -1) {
// 保留首页和目标tab及其右侧的所有tab
const beforeIndex = tabList.value.slice(0, targetIndex);
const hasCloseableLeft = beforeIndex.some(t => t.fullPath !== defaultDashboardPath);
if (hasCloseableLeft) {
tabList.value = tabList.value.filter((t, index) =>
t.fullPath === defaultDashboardPath || index >= targetIndex
);
// 如果关闭的tab中包含了当前激活的tab,则激活目标tab
if (!tabList.value.find(t => t.fullPath === activeTab.value)) {
activeTab.value = targetFullPath;
}
saveTabsToStorage(tabList.value, activeTab.value);
}
}
}
// 关闭右侧(关闭指定tab右侧的所有tab,保留首页和目标tab)
function closeRight(targetFullPath) {
const targetIndex = tabList.value.findIndex((t) => t.fullPath === targetFullPath);
if (targetIndex > -1) {
// 保留首页和目标tab及其左侧的所有tab
const afterIndex = tabList.value.slice(targetIndex + 1);
const hasCloseableRight = afterIndex.length > 0;
if (hasCloseableRight) {
tabList.value = tabList.value.filter((t, index) =>
t.fullPath === defaultDashboardPath || index <= targetIndex
);
// 如果关闭的tab中包含了当前激活的tab,则激活目标tab
if (!tabList.value.find(t => t.fullPath === activeTab.value)) {
activeTab.value = targetFullPath;
}
saveTabsToStorage(tabList.value, activeTab.value);
}
}
}
// 关闭全部,只留首页
function closeAll() {
tabList.value = tabList.value.filter((t) => t.fullPath === defaultDashboardPath);
activeTab.value = defaultDashboardPath;
saveTabsToStorage(tabList.value, activeTab.value);
}
// 设置激活tab(不触发路由跳转,仅用于更新状态)
function setActiveTab(fullPath) {
activeTab.value = fullPath;
saveTabsToStorage(tabList.value, activeTab.value);
}
// 重置 tabs store 到初始状态(登出时使用)
function resetTabs() {
tabList.value = [{ title: '首页', fullPath: defaultDashboardPath, name: 'Dashboard' }];
activeTab.value = defaultDashboardPath;
// 清除 localStorage 中的 tabs 数据
localStorage.removeItem('tabs_list');
localStorage.removeItem('active_tab');
}
return {
tabList,
activeTab,
addTab,
removeTab,
closeOthers,
closeLeft,
closeRight,
closeAll,
setActiveTab,
saveTabsToStorage,
resetTabs,
};
});
// ========== 菜单 Menu Store ==========
export { useMenuStore } from './menu';