hookehuyr

feat(导航): 替换 router-link 为 div 并添加点击事件处理

在 BottomNav.vue 中,将 router-link 替换为 div,并添加 handleNavClick 方法以处理导航点击事件。如果用户未登录且点击了“个人资料”项,则跳转到登录页面。同时,在 HomePage.vue 中,根据当前用户状态动态显示用户信息和头像。
1 +<!--
2 + * @Date: 2025-03-20 20:36:36
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2025-03-21 10:20:44
5 + * @FilePath: /mlaj/src/components/layout/BottomNav.vue
6 + * @Description: 文件描述
7 +-->
1 <template> 8 <template>
2 <nav class="fixed bottom-0 left-0 right-0 bg-white/70 backdrop-blur-lg border-t border-gray-100 z-50"> 9 <nav class="fixed bottom-0 left-0 right-0 bg-white/70 backdrop-blur-lg border-t border-gray-100 z-50">
3 <div class="flex justify-around items-center h-16"> 10 <div class="flex justify-around items-center h-16">
4 - <router-link 11 + <div
5 v-for="item in navItems" 12 v-for="item in navItems"
6 :key="item.name" 13 :key="item.name"
7 - :to="item.path" 14 + @click="handleNavClick(item)"
8 - class="flex flex-col items-center justify-center w-1/4 h-full" 15 + class="flex flex-col items-center justify-center w-1/4 h-full cursor-pointer"
9 :class="{ 16 :class="{
10 'text-green-500': isActive(item.path), 17 'text-green-500': isActive(item.path),
11 'text-gray-500': !isActive(item.path) 18 'text-gray-500': !isActive(item.path)
...@@ -24,16 +31,19 @@ ...@@ -24,16 +31,19 @@
24 v-html="item.icon" 31 v-html="item.icon"
25 /> 32 />
26 <span class="text-xs">{{ item.name }}</span> 33 <span class="text-xs">{{ item.name }}</span>
27 - </router-link> 34 + </div>
28 </div> 35 </div>
29 </nav> 36 </nav>
30 </template> 37 </template>
31 38
32 <script setup> 39 <script setup>
33 import { computed } from 'vue' 40 import { computed } from 'vue'
34 -import { useRoute } from 'vue-router' 41 +import { useRoute, useRouter } from 'vue-router'
42 +import { useAuth } from '@/contexts/auth'
35 43
36 const route = useRoute() 44 const route = useRoute()
45 +const router = useRouter()
46 +const { currentUser } = useAuth()
37 47
38 const navItems = [ 48 const navItems = [
39 { 49 {
...@@ -61,4 +71,12 @@ const navItems = [ ...@@ -61,4 +71,12 @@ const navItems = [
61 const isActive = (path) => { 71 const isActive = (path) => {
62 return route.path === path || (path !== '/' && route.path.startsWith(path)) 72 return route.path === path || (path !== '/' && route.path.startsWith(path))
63 } 73 }
74 +
75 +const handleNavClick = (item) => {
76 + if (item.path === '/profile' && !currentUser.value) {
77 + router.push('/login')
78 + return
79 + }
80 + router.push(item.path)
81 +}
64 </script> 82 </script>
......
...@@ -9,19 +9,19 @@ ...@@ -9,19 +9,19 @@
9 <AppLayout title="亲子学院" :rightContent="rightContent"> 9 <AppLayout title="亲子学院" :rightContent="rightContent">
10 <div class="pb-16 bg-gradient-to-b from-white via-green-50/10 to-blue-50/10"> 10 <div class="pb-16 bg-gradient-to-b from-white via-green-50/10 to-blue-50/10">
11 <!-- Header Section with Welcome & Weather --> 11 <!-- Header Section with Welcome & Weather -->
12 - <div class="px-4 pt-3 pb-4"> 12 + <div v-if="currentUser" class="px-4 pt-3 pb-4">
13 <FrostedGlass class="p-4 rounded-xl mb-4"> 13 <FrostedGlass class="p-4 rounded-xl mb-4">
14 <div class="flex justify-between items-center mb-3"> 14 <div class="flex justify-between items-center mb-3">
15 <div class="flex items-center"> 15 <div class="flex items-center">
16 <div class="w-10 h-10 rounded-full overflow-hidden mr-3"> 16 <div class="w-10 h-10 rounded-full overflow-hidden mr-3">
17 <img 17 <img
18 - src="https://cdn.ipadbiz.cn/mlaj/images/user-avatar-2.jpg" 18 + :src="currentUser.avatar"
19 - alt="王小明" 19 + :alt="currentUser.name"
20 class="w-full h-full object-cover" 20 class="w-full h-full object-cover"
21 @error="handleImageError" /> 21 @error="handleImageError" />
22 </div> 22 </div>
23 <div> 23 <div>
24 - <h2 class="text-xl font-bold">欢迎回来,小明!</h2> 24 + <h2 class="text-xl font-bold">欢迎回来,{{ currentUser.name }}!</h2>
25 <p class="text-sm text-gray-500">{{ formatToday() }}</p> 25 <p class="text-sm text-gray-500">{{ formatToday() }}</p>
26 </div> 26 </div>
27 </div> 27 </div>
...@@ -489,11 +489,15 @@ import LiveStreamCard from '@/components/ui/LiveStreamCard.vue' ...@@ -489,11 +489,15 @@ import LiveStreamCard from '@/components/ui/LiveStreamCard.vue'
489 import ActivityCard from '@/components/ui/ActivityCard.vue' 489 import ActivityCard from '@/components/ui/ActivityCard.vue'
490 import SummerCampCard from '@/components/ui/SummerCampCard.vue' 490 import SummerCampCard from '@/components/ui/SummerCampCard.vue'
491 import { courses, liveStreams, activities, checkInTypes, userRecommendations } from '@/utils/mockData' 491 import { courses, liveStreams, activities, checkInTypes, userRecommendations } from '@/utils/mockData'
492 -import { useTitle } from '@vueuse/core'; 492 +import { useTitle } from '@vueuse/core'
493 +import { useAuth } from '@/contexts/auth'
493 494
494 -const $route = useRoute(); 495 +const $route = useRoute()
495 -const $router = useRouter(); 496 +const $router = useRouter()
496 -useTitle($route.meta.title); 497 +useTitle($route.meta.title)
498 +
499 +// 获取认证状态
500 +const { currentUser } = useAuth()
497 501
498 // 响应式状态 502 // 响应式状态
499 const activeTab = ref('推荐') 503 const activeTab = ref('推荐')
......