# 02-路由和布局设计 ## 目标 配置 Vue Router 路由系统,实现页面布局和导航守卫。 --- ## 前置要求 - 项目结构已初始化 - Vue Router 已安装 --- ## 实施步骤 ### 步骤 1:创建用户 Store 创建 `src/stores/user.ts`: ```typescript import { defineStore } from 'pinia' import { ref, computed } from 'vue' export const useUserStore = defineStore('user', () => { const token = ref(localStorage.getItem('token') || '') const userInfo = ref(null) const isLoggedIn = computed(() => !!token.value) const surveyCompleted = computed(() => userInfo.value?.survey_completed || false) function setToken(newToken: string) { token.value = newToken localStorage.setItem('token', newToken) } function setUserInfo(info: any) { userInfo.value = info } function logout() { token.value = '' userInfo.value = null localStorage.removeItem('token') } return { token, userInfo, isLoggedIn, surveyCompleted, setToken, setUserInfo, logout, } }) ``` ### 步骤 2:创建路由配置 创建 `src/router/index.ts`: ```typescript import { createRouter, createWebHistory } from 'vue-router' import type { RouteRecordRaw } from 'vue-router' import { useUserStore } from '@/stores/user' // 布局组件 import MainLayout from '@/components/common/MainLayout.vue' import AuthLayout from '@/components/common/AuthLayout.vue' const routes: RouteRecordRaw[] = [ // 认证相关页面 { path: '/auth', component: AuthLayout, children: [ { path: 'login', name: 'Login', component: () => import('@/views/auth/Login.vue'), meta: { title: '登录' } }, { path: 'register', name: 'Register', component: () => import('@/views/auth/Register.vue'), meta: { title: '注册' } }, ], }, // 健康调查(新用户必经) { path: '/survey', component: MainLayout, meta: { requiresAuth: true }, children: [ { path: '', name: 'Survey', component: () => import('@/views/survey/Index.vue'), meta: { title: '健康调查' } }, ], }, // 体质测评 { path: '/constitution', component: MainLayout, meta: { requiresAuth: true, requiresSurvey: true }, children: [ { path: '', name: 'Constitution', component: () => import('@/views/constitution/Index.vue'), meta: { title: '体质测评' } }, { path: 'result', name: 'ConstitutionResult', component: () => import('@/views/constitution/Result.vue'), meta: { title: '体质结果' } }, ], }, // 主要功能页面 { path: '/', component: MainLayout, meta: { requiresAuth: true, requiresSurvey: true }, children: [ { path: '', redirect: '/chat' }, { path: 'chat', name: 'Chat', component: () => import('@/views/chat/Index.vue'), meta: { title: 'AI问诊' } }, { path: 'chat/:id', name: 'ChatDetail', component: () => import('@/views/chat/Detail.vue'), meta: { title: '对话详情' } }, { path: 'profile', name: 'Profile', component: () => import('@/views/profile/Index.vue'), meta: { title: '个人中心' } }, { path: 'health-record', name: 'HealthRecord', component: () => import('@/views/profile/HealthRecord.vue'), meta: { title: '健康档案' } }, ], }, // 404 { path: '/:pathMatch(.*)*', redirect: '/' }, ] const router = createRouter({ history: createWebHistory(), routes, }) // 路由守卫 router.beforeEach((to, from, next) => { const userStore = useUserStore() // 设置页面标题 document.title = (to.meta.title as string) + ' - 健康AI助手' || '健康AI助手' // 检查是否需要登录 if (to.meta.requiresAuth && !userStore.isLoggedIn) { next({ path: '/auth/login', query: { redirect: to.fullPath } }) return } // 检查是否需要完成调查 if (to.meta.requiresSurvey && !userStore.surveyCompleted) { // 如果已登录但未完成调查,跳转到调查页 if (to.path !== '/survey') { next('/survey') return } } // 已登录用户访问登录页,跳转到首页 if ((to.path === '/auth/login' || to.path === '/auth/register') && userStore.isLoggedIn) { next('/') return } next() }) export default router ``` ### 步骤 3:创建认证布局组件 创建 `src/components/common/AuthLayout.vue`: ```vue ``` ### 步骤 4:创建主布局组件 创建 `src/components/common/MainLayout.vue`: ```vue ``` ### 步骤 5:创建 Logo 占位 创建 `src/assets/logo.svg`: ```svg ``` ### 步骤 6:更新 App.vue 更新 `src/App.vue`: ```vue ``` ### 步骤 7:创建用户 API 创建 `src/api/user.ts`: ```typescript import request from './request' export const getUserProfile = () => { return request.get('/user/profile') } export const updateUserProfile = (data: any) => { return request.put('/user/profile', data) } export const getHealthProfile = () => { return request.get('/user/health-profile') } ``` --- ## 需要创建的文件清单 | 文件路径 | 说明 | |----------|------| | `src/stores/user.ts` | 用户状态管理 | | `src/router/index.ts` | 路由配置 | | `src/components/common/AuthLayout.vue` | 认证布局 | | `src/components/common/MainLayout.vue` | 主布局 | | `src/assets/logo.svg` | Logo 图标 | | `src/App.vue` | 根组件(更新) | | `src/api/user.ts` | 用户 API | --- ## 路由结构说明 | 路径 | 组件 | 说明 | |------|------|------| | /auth/login | Login.vue | 登录页 | | /auth/register | Register.vue | 注册页 | | /survey | Survey/Index.vue | 健康调查 | | /constitution | Constitution/Index.vue | 体质测评 | | /constitution/result | Constitution/Result.vue | 体质结果 | | /chat | Chat/Index.vue | AI问诊列表 | | /chat/:id | Chat/Detail.vue | 对话详情 | | /profile | Profile/Index.vue | 个人中心 | | /health-record | Profile/HealthRecord.vue | 健康档案 | --- ## 验收标准 - [ ] 路由配置正确加载 - [ ] 未登录自动跳转登录页 - [ ] 登录布局显示正常 - [ ] 主布局侧边栏显示正常 - [ ] 路由守卫逻辑正确 --- ## 预计耗时 25-30 分钟 --- ## 下一步 完成后进入 `03-Web前端开发/03-用户认证页面.md`