tool.xpcool.com/src/layout/SideNav.vue
夏犀麟 42d4de46ba feat(tools): 添加工具分类机制并新增多个生活助手工具
- 实现工具分类功能,支持按工作/生活等维度分组展示
- 新增BMI计算器,支持按中国成人标准分级与健康体重范围
- 新增房贷计算器,支持等额本息与等额本金两种还款方式对比
- 新增账单拆分工具,支持多人AA制自动生成转账方案
- 新增随机决定工具,支持选项抽签与随机数生成
- 新增番茄钟功能,支持专注与休息倒计时及轮数记录
- 更新首页与侧边栏按分类分组渲染工具列表
- 优化工具注册表支持category字段配置分类归属
2026-08-22 15:25:29 +08:00

85 lines
2.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<nav class="side-nav">
<router-link to="/" class="nav-item" :class="{ active: route.path === '/' }" @click="emit('navigate')">
<HomeIcon class="nav-icon" />
<span>首页</span>
</router-link>
<template v-for="group in groups" :key="group.category.key">
<div class="nav-group-title">{{ group.category.label }}</div>
<router-link
v-for="tool in group.items"
:key="tool.path"
:to="`/${tool.path}`"
class="nav-item"
:class="{ active: route.path === `/${tool.path}` }"
@click="emit('navigate')"
>
<component :is="tool.icon" class="nav-icon" />
<span>{{ tool.name }}</span>
</router-link>
</template>
</nav>
</template>
<script setup lang="ts">
import { useRoute } from 'vue-router'
import { HomeIcon } from 'tdesign-icons-vue-next'
import { groupedTools } from '@/router/tools'
/**
* 侧边导航数据源为工具注册表 tools.ts按分类分组渲染
* PC 端渲染在左侧固定栏移动端渲染在抽屉内点击后由父组件关闭抽屉
*/
const route = useRoute()
/** 分类分组新增分类自动出现无需改动本组件 */
const groups = groupedTools()
const emit = defineEmits<{
/** 点击菜单项后通知父组件移动端用于关闭抽屉 */
navigate: []
}>()
</script>
<style scoped>
.side-nav {
display: flex;
flex-direction: column;
gap: 2px;
}
.nav-group-title {
padding: 8px 12px 4px;
font-size: 12px;
color: var(--td-text-color-placeholder);
}
.nav-item {
display: flex;
align-items: center;
gap: 10px;
padding: 9px 12px;
border-radius: 6px;
font-size: 14px;
color: var(--td-text-color-secondary);
text-decoration: none;
transition:
background-color 0.15s,
color 0.15s;
}
.nav-item:hover {
background: var(--td-bg-color-secondarycontainer);
color: var(--td-text-color-primary);
}
.nav-item.active {
background: var(--td-brand-color-light);
color: var(--td-brand-color);
font-weight: 500;
}
.nav-icon {
width: 18px;
height: 18px;
flex-shrink: 0;
}
</style>