hookehuyr

feat: 添加页面标题动态设置功能

使用@vueuse/core的useTitle方法动态设置页面标题,并更新路由元信息中的标题为中文
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
16 "devDependencies": { 16 "devDependencies": {
17 "@vitejs/plugin-vue": "^5.2.1", 17 "@vitejs/plugin-vue": "^5.2.1",
18 "@vitejs/plugin-vue-jsx": "^4.1.2", 18 "@vitejs/plugin-vue-jsx": "^4.1.2",
19 + "@vueuse/core": "^13.0.0",
19 "autoprefixer": "^10.4.19", 20 "autoprefixer": "^10.4.19",
20 "postcss": "^8.4.35", 21 "postcss": "^8.4.35",
21 "tailwindcss": "^3.4.1", 22 "tailwindcss": "^3.4.1",
...@@ -1175,6 +1176,12 @@ ...@@ -1175,6 +1176,12 @@
1175 "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", 1176 "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
1176 "dev": true 1177 "dev": true
1177 }, 1178 },
1179 + "node_modules/@types/web-bluetooth": {
1180 + "version": "0.0.21",
1181 + "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.21.tgz",
1182 + "integrity": "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==",
1183 + "dev": true
1184 + },
1178 "node_modules/@vant/popperjs": { 1185 "node_modules/@vant/popperjs": {
1179 "version": "1.3.0", 1186 "version": "1.3.0",
1180 "resolved": "https://registry.npmjs.org/@vant/popperjs/-/popperjs-1.3.0.tgz", 1187 "resolved": "https://registry.npmjs.org/@vant/popperjs/-/popperjs-1.3.0.tgz",
...@@ -1392,6 +1399,44 @@ ...@@ -1392,6 +1399,44 @@
1392 "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.13.tgz", 1399 "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.13.tgz",
1393 "integrity": "sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==" 1400 "integrity": "sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ=="
1394 }, 1401 },
1402 + "node_modules/@vueuse/core": {
1403 + "version": "13.0.0",
1404 + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-13.0.0.tgz",
1405 + "integrity": "sha512-rkgb4a8/0b234lMGCT29WkCjPfsX0oxrIRR7FDndRoW3FsaC9NBzefXg/9TLhAgwM11f49XnutshM4LzJBrQ5g==",
1406 + "dev": true,
1407 + "dependencies": {
1408 + "@types/web-bluetooth": "^0.0.21",
1409 + "@vueuse/metadata": "13.0.0",
1410 + "@vueuse/shared": "13.0.0"
1411 + },
1412 + "funding": {
1413 + "url": "https://github.com/sponsors/antfu"
1414 + },
1415 + "peerDependencies": {
1416 + "vue": "^3.5.0"
1417 + }
1418 + },
1419 + "node_modules/@vueuse/metadata": {
1420 + "version": "13.0.0",
1421 + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-13.0.0.tgz",
1422 + "integrity": "sha512-TRNksqmvtvqsuHf7bbgH9OSXEV2b6+M3BSN4LR5oxWKykOFT9gV78+C2/0++Pq9KCp9KQ1OQDPvGlWNQpOb2Mw==",
1423 + "dev": true,
1424 + "funding": {
1425 + "url": "https://github.com/sponsors/antfu"
1426 + }
1427 + },
1428 + "node_modules/@vueuse/shared": {
1429 + "version": "13.0.0",
1430 + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-13.0.0.tgz",
1431 + "integrity": "sha512-9MiHhAPw+sqCF/RLo8V6HsjRqEdNEWVpDLm2WBRW2G/kSQjb8X901sozXpSCaeLG0f7TEfMrT4XNaA5m1ez7Dg==",
1432 + "dev": true,
1433 + "funding": {
1434 + "url": "https://github.com/sponsors/antfu"
1435 + },
1436 + "peerDependencies": {
1437 + "vue": "^3.5.0"
1438 + }
1439 + },
1395 "node_modules/ansi-regex": { 1440 "node_modules/ansi-regex": {
1396 "version": "6.1.0", 1441 "version": "6.1.0",
1397 "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", 1442 "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
17 "devDependencies": { 17 "devDependencies": {
18 "@vitejs/plugin-vue": "^5.2.1", 18 "@vitejs/plugin-vue": "^5.2.1",
19 "@vitejs/plugin-vue-jsx": "^4.1.2", 19 "@vitejs/plugin-vue-jsx": "^4.1.2",
20 + "@vueuse/core": "^13.0.0",
20 "autoprefixer": "^10.4.19", 21 "autoprefixer": "^10.4.19",
21 "postcss": "^8.4.35", 22 "postcss": "^8.4.35",
22 "tailwindcss": "^3.4.1", 23 "tailwindcss": "^3.4.1",
......
...@@ -12,57 +12,57 @@ const routes = [ ...@@ -12,57 +12,57 @@ const routes = [
12 path: '/', 12 path: '/',
13 name: 'HomePage', 13 name: 'HomePage',
14 component: () => import('../views/HomePage.vue'), 14 component: () => import('../views/HomePage.vue'),
15 - meta: { title: 'HomePage' }, 15 + meta: { title: '首页' },
16 }, 16 },
17 { 17 {
18 path: '/courses', 18 path: '/courses',
19 name: 'Courses', 19 name: 'Courses',
20 component: () => import('../views/courses/CoursesPage.vue'), 20 component: () => import('../views/courses/CoursesPage.vue'),
21 - meta: { title: 'Courses' }, 21 + meta: { title: '课程列表' },
22 }, 22 },
23 { 23 {
24 path: '/courses/:id', 24 path: '/courses/:id',
25 name: 'CourseDetail', 25 name: 'CourseDetail',
26 component: () => import('../views/courses/CourseDetailPage.vue'), 26 component: () => import('../views/courses/CourseDetailPage.vue'),
27 - meta: { title: 'CourseDetail' }, 27 + meta: { title: '课程详情' },
28 }, 28 },
29 { 29 {
30 path: '/profile', 30 path: '/profile',
31 name: 'Profile', 31 name: 'Profile',
32 component: () => import('../views/profile/ProfilePage.vue'), 32 component: () => import('../views/profile/ProfilePage.vue'),
33 - meta: { title: 'Profile' }, 33 + meta: { title: '个人中心' },
34 }, 34 },
35 { 35 {
36 path: '/login', 36 path: '/login',
37 name: 'Login', 37 name: 'Login',
38 component: () => import('../views/auth/LoginPage.vue'), 38 component: () => import('../views/auth/LoginPage.vue'),
39 - meta: { title: 'Login' } 39 + meta: { title: '登录' }
40 }, 40 },
41 { 41 {
42 path: '/register', 42 path: '/register',
43 name: 'Register', 43 name: 'Register',
44 component: () => import('../views/auth/RegisterPage.vue'), 44 component: () => import('../views/auth/RegisterPage.vue'),
45 - meta: { title: 'Register' } 45 + meta: { title: '注册' }
46 }, 46 },
47 { 47 {
48 path: '/activities', 48 path: '/activities',
49 name: 'Activities', 49 name: 'Activities',
50 component: () => import('../views/activities/ActivitiesPage.vue'), 50 component: () => import('../views/activities/ActivitiesPage.vue'),
51 - meta: { title: 'Activities' } 51 + meta: { title: '活动列表' }
52 }, 52 },
53 { 53 {
54 path: '/activities/:id', 54 path: '/activities/:id',
55 name: 'ActivityDetail', 55 name: 'ActivityDetail',
56 component: () => import('../views/activities/ActivityDetailPage.vue'), 56 component: () => import('../views/activities/ActivityDetailPage.vue'),
57 props: true, 57 props: true,
58 - meta: { title: 'Home' } 58 + meta: { title: '活动详情' }
59 }, 59 },
60 { 60 {
61 path: '/checkout', 61 path: '/checkout',
62 name: 'CheckoutPage', 62 name: 'CheckoutPage',
63 component: () => import('../views/checkout/CheckoutPage.vue'), 63 component: () => import('../views/checkout/CheckoutPage.vue'),
64 props: true, 64 props: true,
65 - meta: { title: 'Home' } 65 + meta: { title: '结账' }
66 }, 66 },
67 ] 67 ]
68 68
......
1 <!-- 1 <!--
2 * @Date: 2025-03-20 19:55:21 2 * @Date: 2025-03-20 19:55:21
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-03-20 22:39:23 4 + * @LastEditTime: 2025-03-20 23:13:20
5 * @FilePath: /mlaj/src/views/HomePage.vue 5 * @FilePath: /mlaj/src/views/HomePage.vue
6 * @Description: 文件描述 6 * @Description: 文件描述
7 --> 7 -->
...@@ -450,6 +450,7 @@ ...@@ -450,6 +450,7 @@
450 450
451 <script setup lang="jsx"> 451 <script setup lang="jsx">
452 import { ref, onMounted, onUnmounted, defineComponent, h } from 'vue' 452 import { ref, onMounted, onUnmounted, defineComponent, h } from 'vue'
453 +import { useRoute, useRouter } from 'vue-router'
453 import AppLayout from '@/components/layout/AppLayout.vue' 454 import AppLayout from '@/components/layout/AppLayout.vue'
454 import FrostedGlass from '@/components/ui/FrostedGlass.vue' 455 import FrostedGlass from '@/components/ui/FrostedGlass.vue'
455 import CourseCard from '@/components/ui/CourseCard.vue' 456 import CourseCard from '@/components/ui/CourseCard.vue'
...@@ -457,6 +458,11 @@ import LiveStreamCard from '@/components/ui/LiveStreamCard.vue' ...@@ -457,6 +458,11 @@ import LiveStreamCard from '@/components/ui/LiveStreamCard.vue'
457 import ActivityCard from '@/components/ui/ActivityCard.vue' 458 import ActivityCard from '@/components/ui/ActivityCard.vue'
458 import SummerCampCard from '@/components/ui/SummerCampCard.vue' 459 import SummerCampCard from '@/components/ui/SummerCampCard.vue'
459 import { courses, liveStreams, activities, checkInTypes, userRecommendations } from '@/utils/mockData' 460 import { courses, liveStreams, activities, checkInTypes, userRecommendations } from '@/utils/mockData'
461 +import { useTitle } from '@vueuse/core';
462 +
463 +const $route = useRoute();
464 +const $router = useRouter();
465 +useTitle($route.meta.title);
460 466
461 // 响应式状态 467 // 响应式状态
462 const activeTab = ref('推荐') 468 const activeTab = ref('推荐')
......
...@@ -149,10 +149,14 @@ ...@@ -149,10 +149,14 @@
149 149
150 <script setup> 150 <script setup>
151 import { ref, computed, defineComponent, h } from 'vue' 151 import { ref, computed, defineComponent, h } from 'vue'
152 +import { useRoute, useRouter } from 'vue-router'
152 import AppLayout from '@/components/layout/AppLayout.vue' 153 import AppLayout from '@/components/layout/AppLayout.vue'
153 import ActivityCard from '@/components/ui/ActivityCard.vue' 154 import ActivityCard from '@/components/ui/ActivityCard.vue'
154 import { activities } from '@/utils/mockData' 155 import { activities } from '@/utils/mockData'
155 - 156 +import { useTitle } from '@vueuse/core';
157 +const $route = useRoute();
158 +const $router = useRouter();
159 +useTitle($route.meta.title);
156 // 响应式状态 160 // 响应式状态
157 const activeFilter = ref('全部') 161 const activeFilter = ref('全部')
158 const locationFilter = ref('') 162 const locationFilter = ref('')
......
...@@ -4,7 +4,10 @@ import { useRoute, useRouter } from "vue-router"; ...@@ -4,7 +4,10 @@ import { useRoute, useRouter } from "vue-router";
4 import AppLayout from "@/components/layout/AppLayout.vue"; 4 import AppLayout from "@/components/layout/AppLayout.vue";
5 import FrostedGlass from "@/components/ui/FrostedGlass.vue"; 5 import FrostedGlass from "@/components/ui/FrostedGlass.vue";
6 import { activities } from "@/utils/mockData"; 6 import { activities } from "@/utils/mockData";
7 - 7 +import { useTitle } from '@vueuse/core';
8 +const $route = useRoute();
9 +const $router = useRouter();
10 +useTitle($route.meta.title);
8 const route = useRoute(); 11 const route = useRoute();
9 const router = useRouter(); 12 const router = useRouter();
10 const activity = ref(null); 13 const activity = ref(null);
......
...@@ -123,10 +123,13 @@ ...@@ -123,10 +123,13 @@
123 123
124 <script setup> 124 <script setup>
125 import { ref } from 'vue' 125 import { ref } from 'vue'
126 -import { useRouter } from 'vue-router' 126 +import { useRoute, useRouter } from 'vue-router'
127 import FrostedGlass from '@/components/ui/FrostedGlass.vue' 127 import FrostedGlass from '@/components/ui/FrostedGlass.vue'
128 import { useAuth } from '@/contexts/auth' 128 import { useAuth } from '@/contexts/auth'
129 - 129 +import { useTitle } from '@vueuse/core';
130 +const $route = useRoute();
131 +const $router = useRouter();
132 +useTitle($route.meta.title);
130 const router = useRouter() 133 const router = useRouter()
131 const { login } = useAuth() 134 const { login } = useAuth()
132 135
......
...@@ -152,10 +152,13 @@ ...@@ -152,10 +152,13 @@
152 152
153 <script setup> 153 <script setup>
154 import { ref, reactive } from 'vue' 154 import { ref, reactive } from 'vue'
155 -import { useRouter } from 'vue-router' 155 +import { useRoute, useRouter } from 'vue-router'
156 import FrostedGlass from '@/components/ui/FrostedGlass.vue' 156 import FrostedGlass from '@/components/ui/FrostedGlass.vue'
157 import { useAuth } from '@/contexts/auth' 157 import { useAuth } from '@/contexts/auth'
158 - 158 +import { useTitle } from '@vueuse/core';
159 +const $route = useRoute();
160 +const $router = useRouter();
161 +useTitle($route.meta.title);
159 const router = useRouter() 162 const router = useRouter()
160 const { login } = useAuth() 163 const { login } = useAuth()
161 164
......
...@@ -267,12 +267,15 @@ ...@@ -267,12 +267,15 @@
267 267
268 <script setup> 268 <script setup>
269 import { ref } from 'vue' 269 import { ref } from 'vue'
270 -import { useRouter } from 'vue-router' 270 +import { useRoute, useRouter } from 'vue-router'
271 import AppLayout from '@/components/layout/AppLayout.vue' 271 import AppLayout from '@/components/layout/AppLayout.vue'
272 import FrostedGlass from '@/components/ui/FrostedGlass.vue' 272 import FrostedGlass from '@/components/ui/FrostedGlass.vue'
273 import ConfirmDialog from '@/components/ui/ConfirmDialog.vue' 273 import ConfirmDialog from '@/components/ui/ConfirmDialog.vue'
274 import { useCart } from '@/contexts/cart' 274 import { useCart } from '@/contexts/cart'
275 - 275 +import { useTitle } from '@vueuse/core';
276 +const $route = useRoute();
277 +const $router = useRouter();
278 +useTitle($route.meta.title);
276 const router = useRouter() 279 const router = useRouter()
277 const { items: cartItems, getTotalPrice, handleCheckout, clearCart, removeFromCart } = useCart() 280 const { items: cartItems, getTotalPrice, handleCheckout, clearCart, removeFromCart } = useCart()
278 281
......
...@@ -260,7 +260,10 @@ import AppLayout from '@/components/layout/AppLayout.vue' ...@@ -260,7 +260,10 @@ import AppLayout from '@/components/layout/AppLayout.vue'
260 import FrostedGlass from '@/components/ui/FrostedGlass.vue' 260 import FrostedGlass from '@/components/ui/FrostedGlass.vue'
261 import { courses } from '@/utils/mockData' 261 import { courses } from '@/utils/mockData'
262 import { useCart } from '@/contexts/cart' 262 import { useCart } from '@/contexts/cart'
263 - 263 +import { useTitle } from '@vueuse/core';
264 +const $route = useRoute();
265 +const $router = useRouter();
266 +useTitle($route.meta.title);
264 const route = useRoute() 267 const route = useRoute()
265 const router = useRouter() 268 const router = useRouter()
266 const course = ref(null) 269 const course = ref(null)
......
...@@ -82,13 +82,17 @@ ...@@ -82,13 +82,17 @@
82 82
83 <script setup lang="jsx"> 83 <script setup lang="jsx">
84 import { computed, defineComponent, h } from "vue"; 84 import { computed, defineComponent, h } from "vue";
85 +import { useRoute, useRouter } from 'vue-router'
85 import AppLayout from "@/components/layout/AppLayout.vue"; 86 import AppLayout from "@/components/layout/AppLayout.vue";
86 import SearchBar from "@/components/ui/SearchBar.vue"; 87 import SearchBar from "@/components/ui/SearchBar.vue";
87 import FrostedGlass from "@/components/ui/FrostedGlass.vue"; 88 import FrostedGlass from "@/components/ui/FrostedGlass.vue";
88 import CourseCard from "@/components/ui/CourseCard.vue"; 89 import CourseCard from "@/components/ui/CourseCard.vue";
89 import LiveStreamCard from "@/components/ui/LiveStreamCard.vue"; 90 import LiveStreamCard from "@/components/ui/LiveStreamCard.vue";
90 import { featuredCourse, liveStreams, courses } from "@/utils/mockData"; 91 import { featuredCourse, liveStreams, courses } from "@/utils/mockData";
91 - 92 +import { useTitle } from '@vueuse/core';
93 +const $route = useRoute();
94 +const $router = useRouter();
95 +useTitle($route.meta.title);
92 // Search handler 96 // Search handler
93 const handleSearch = (query) => { 97 const handleSearch = (query) => {
94 console.log("Searching for:", query); 98 console.log("Searching for:", query);
......
...@@ -128,14 +128,17 @@ ...@@ -128,14 +128,17 @@
128 128
129 <script setup> 129 <script setup>
130 import { ref, h } from 'vue' 130 import { ref, h } from 'vue'
131 -import { useRouter } from 'vue-router' 131 +import { useRoute, useRouter } from 'vue-router'
132 import AppLayout from '@/components/layout/AppLayout.vue' 132 import AppLayout from '@/components/layout/AppLayout.vue'
133 import FrostedGlass from '@/components/ui/FrostedGlass.vue' 133 import FrostedGlass from '@/components/ui/FrostedGlass.vue'
134 import MenuItem from '@/components/ui/MenuItem.vue' 134 import MenuItem from '@/components/ui/MenuItem.vue'
135 import { useAuth } from '@/contexts/auth' 135 import { useAuth } from '@/contexts/auth'
136 import { userProfile, checkInTypes } from '@/utils/mockData' 136 import { userProfile, checkInTypes } from '@/utils/mockData'
137 - 137 +import { useTitle } from '@vueuse/core';
138 const router = useRouter() 138 const router = useRouter()
139 +const $route = useRoute();
140 +const $router = useRouter();
141 +useTitle($route.meta.title);
139 const { currentUser, logout } = useAuth() 142 const { currentUser, logout } = useAuth()
140 const profile = ref(userProfile) 143 const profile = ref(userProfile)
141 144
......