优化:目录状态做成全局状态

This commit is contained in:
马丁 2026-05-19 13:05:31 +08:00
parent 85a2590676
commit 59edb13f53
2 changed files with 50 additions and 31 deletions

View File

@ -0,0 +1,44 @@
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import type { CategoryTreeNode } from '@/api/category'
export const useMenuStore = defineStore('menu', () => {
/** 分类树(顶层) */
const categoryTree = ref<CategoryTreeNode[]>([])
/** 每层选中的 id[layer0, layer1?, layer2?] */
const layerActiveValues = ref<string[]>([])
/** 过滤:仅当 forceShow 明确为 false 时不显示其他null/undefined/true 等)均显示;排除 forceHide 的节点 */
function filterVisible(nodes: CategoryTreeNode[] | undefined): CategoryTreeNode[] {
if (!nodes?.length) return []
return nodes.filter((n) => n.forceShow !== false && !n.forceHide)
}
/** 当前展示的层级数据:[[layer0], [layer1]?, [layer2]?] */
const categoryLayers = computed(() => {
const root = filterVisible(categoryTree.value)
if (root.length === 0) return []
const layers: CategoryTreeNode[][] = [root]
const active = layerActiveValues.value
let currentNodes = root
for (let i = 0; i < 2; i++) {
const selectedId = active[i]
const node = selectedId ? currentNodes.find((n) => n.id === selectedId) : currentNodes[0]
const children = filterVisible(node?.children)
if (children.length === 0) break
layers.push(children)
currentNodes = children
}
return layers
})
return {
categoryTree,
layerActiveValues,
categoryLayers,
filterVisible
}
})

View File

@ -155,13 +155,14 @@ import {
enrichWithIcons,
getPmTagMain,
MOCK_CATEGORY_TREE,
type CategoryTreeNode,
} from '../api/category'
import { USE_MOCK_CATEGORY } from '../config/mock'
import { useI18n } from 'vue-i18n'
import { useSearchHistory } from '../composables/useSearchHistory'
import { useToastStore } from '../stores/toast'
import { useLocaleStore } from '../stores/locale'
import { useMenuStore } from '../stores/menu'
import { storeToRefs } from 'pinia'
const { mobile } = useDisplay()
const { t } = useI18n()
@ -169,10 +170,10 @@ const searchHistory = useSearchHistory()
const searchHistoryList = computed(() => searchHistory.list.value)
const isMobile = computed(() => mobile.value)
/** 分类树(顶层) */
const categoryTree = ref<CategoryTreeNode[]>([])
/** 每层选中的 id[layer0, layer1?, layer2?] */
const layerActiveValues = ref<string[]>([])
const menuStore = useMenuStore()
const { categoryTree, layerActiveValues, categoryLayers } = storeToRefs(menuStore)
const { filterVisible } = menuStore
/** 第三层搜索框是否展开 */
const searchExpanded = ref(false)
/** 搜索关键词 */
@ -225,12 +226,6 @@ function doSearch(keyword: string) {
loadEvents(1, false, keyword)
}
/** 过滤:仅当 forceShow 明确为 false 时不显示其他null/undefined/true 等)均显示;排除 forceHide 的节点 */
function filterVisible(nodes: CategoryTreeNode[] | undefined): CategoryTreeNode[] {
if (!nodes?.length) return []
return nodes.filter((n) => n.forceShow !== false && !n.forceHide)
}
/** 当前选中分类的 tagIds收集所有选中层级节点的 tagId 数组(含父级),用于事件筛选 */
const activeTagIds = computed(() => {
const activeIds = layerActiveValues.value
@ -255,26 +250,6 @@ const activeTagIds = computed(() => {
return Array.from(tagIdSet)
})
/** 当前展示的层级数据:[[layer0], [layer1]?, [layer2]?] */
const categoryLayers = computed(() => {
const root = filterVisible(categoryTree.value)
if (root.length === 0) return []
const layers: CategoryTreeNode[][] = [root]
const active = layerActiveValues.value
let currentNodes = root
for (let i = 0; i < 2; i++) {
const selectedId = active[i]
const node = selectedId ? currentNodes.find((n) => n.id === selectedId) : currentNodes[0]
const children = filterVisible(node?.children)
if (children.length === 0) break
layers.push(children)
currentNodes = children
}
return layers
})
/** 分类选中时:若有 children 则展开下一层并默认选中第一个,并重新加载列表 */
function onCategorySelect(layerIndex: number, selectedId: string) {
if (!selectedId || layerActiveValues.value[layerIndex] === selectedId) {