3.2 KiB
3.2 KiB
Home.vue
路径:src/views/Home.vue
功能用途
首页,展示分类导航栏(三层级)、事件卡片列表。支持分类筛选、搜索、下拉刷新、触底加载更多。
核心能力
- 分类导航:三层级分类选择(一级
v-tabs、二级v-chip、三级v-tabs) - 事件列表:卡片式展示,支持下拉刷新、触底加载
- 搜索:可按关键词搜索事件
- 分类筛选:选中分类后,自动提取所有层级节点的
tagIds进行事件筛选;切换语言时重新请求分类接口并刷新列表
UI 细节
-
卡片阴影不裁剪:列表容器
.home-list-scroll不使用overflow-x: hidden,避免卡片两侧阴影被裁剪 -
分类行分隔:
.home-category-layer1-row底部有淡色投影,增强与下方内容的层次感 -
第一层操作按钮:已移除右侧的搜索/筛选图标;搜索浮层通过
initialSearchExpanded(供/search路由使用)控制展开
数据流
PmTagCatalogItem.tagId = [1351]
↓ mapCatalogToTreeNode
CategoryTreeNode.tagIds = [1351]
↓ 用户选择分类(如:政治 → 特朗普)
activeTagIds = [1351, 1368] // 合并所有选中层级的 tagIds
↓ getPmEventPublic
?tagIds=1351&tagIds=1368
核心计算属性
activeTagIds
收集所有选中层级节点的 tagIds(含父级),用于事件筛选:
const activeTagIds = computed(() => {
const activeIds = layerActiveValues.value
const tagIdSet = new Set<number>()
// 遍历每一层选中的节点,收集所有 tagIds(含父级)
let currentNodes = filterVisible(categoryTree.value)
for (let i = 0; i < activeIds.length; i++) {
const selectedId = activeIds[i]
if (!selectedId) continue
const node = currentNodes.find((n) => n.id === selectedId)
if (node?.tagIds && node.tagIds.length > 0) {
node.tagIds.forEach((id) => tagIdSet.add(id))
}
currentNodes = filterVisible(node?.children)
}
return Array.from(tagIdSet) // 去重后的数组
})
示例:
- 选中「政治」(tagIds: [1351])→ activeTagIds = [1351]
- 选中「政治 → 特朗普」(tagIds: [1351] + [1368])→ activeTagIds = [1351, 1368]
使用方式
无需手动调用,路由 / 自动加载。
扩展方式
- 新增分类层级:修改
MAX_LAYER常量,调整模板渲染逻辑 - 自定义筛选逻辑:修改
activeTagIds计算属性 - 列表缓存策略:调整
getEventListCache/setEventListCache
二级分类 Chip 样式
- 未选中:
variant="outlined"(白底灰边黑字,接近 Vuetify 默认 Chip 外观) - 选中:
variant="tonal" + color="primary"(浅蓝底强调,文字为主题主色)
一级/三级 Tabs 样式(Home 页定制)
- 无下划线:隐藏 Vuetify tabs 的 slider/indicator
- 选中加粗:选中 tab 使用更粗字重
- 无点击水波纹:禁用 ripple(避免点击涟漪效果)
- 无 hover 效果:禁用鼠标悬停时的背景/遮罩变化
- 更紧凑:取消
v-tab默认min-width限制,避免强制占宽 - 第三层更紧凑:三级 tabs 的高度收敛到约 28px(接近 2×字体高度)