11<script setup lang="ts">
2- import { computed , onMounted , onUnmounted , ref } from " vue" ;
2+ import { computed , onMounted , onUnmounted , ref , watch } from " vue" ;
3+ import { useI18n } from " vue-i18n" ;
34
45import AboutSection from " ./sections/AboutSection.vue" ;
56import AchievementsSection from " ./sections/AchievementsSection.vue" ;
@@ -9,16 +10,21 @@ import MembersSection from "./sections/MembersSection.vue";
910import NewsSection from " ./sections/NewsSection.vue" ;
1011import ProjectsSection from " ./sections/ProjectsSection.vue" ;
1112
12- type Lang = " zh " | " en " | " ja " ;
13+ import type { Lang } from " ./i18n " ;
1314
14- const currentLang = ref <Lang >(" zh" );
15+ const { t, locale } = useI18n ({ useScope: " global" });
16+
17+ const currentLang = computed <Lang >({
18+ get : () => locale .value as Lang ,
19+ set : (lang ) => {
20+ locale .value = lang ;
21+ },
22+ });
1523const isLanguageOpen = ref (false );
1624const isMenuOpen = ref (false );
1725
1826const languageLabel = computed (() => {
19- if (currentLang .value === " zh" ) return " 🇨🇳 中文" ;
20- if (currentLang .value === " ja" ) return " 🇯🇵 日本語" ;
21- return " 🇬🇧 English" ;
27+ return t (` language.${currentLang .value } ` );
2228});
2329
2430const scrollProgress = ref (0 );
@@ -44,7 +50,7 @@ function closeNavMenu() {
4450 isMenuOpen .value = false ;
4551}
4652
47- function applyLanguageDom (lang : Lang ) {
53+ function applyLocaleDom (lang : Lang ) {
4854 document .documentElement .lang = lang === " zh" ? " zh-CN" : lang === " en" ? " en-US" : " ja-JP" ;
4955
5056 const titles: Record <Lang , string > = {
@@ -53,14 +59,6 @@ function applyLanguageDom(lang: Lang) {
5359 ja: " RushDB - 無限の進歩" ,
5460 };
5561 document .title = titles [lang ];
56-
57- document .querySelectorAll <HTMLElement >(" .lang-btn" ).forEach ((btn ) => {
58- btn .classList .toggle (" active" , btn .dataset .lang === lang );
59- });
60-
61- document .querySelectorAll <HTMLElement >(" .lang-content" ).forEach ((el ) => {
62- el .classList .toggle (" active" , el .classList .contains (` lang-${lang } ` ));
63- });
6462}
6563
6664async function detectLanguageByLocation(): Promise <Lang > {
@@ -91,7 +89,6 @@ function switchLanguage(lang: Lang) {
9189 currentLang .value = lang ;
9290 hideLanguageSwitcher ();
9391 localStorage .setItem (" rushdb-language" , lang );
94- applyLanguageDom (lang );
9592}
9693
9794function updateScrollEffects() {
@@ -202,6 +199,14 @@ onMounted(async () => {
202199 setupMemberCardHoverZIndex ();
203200});
204201
202+ watch (
203+ () => currentLang .value ,
204+ (lang ) => {
205+ applyLocaleDom (lang );
206+ },
207+ { immediate: true }
208+ );
209+
205210onUnmounted (() => {
206211 window .removeEventListener (" scroll" , onScroll );
207212 window .removeEventListener (" pointermove" , onPointerMove );
@@ -221,49 +226,46 @@ onUnmounted(() => {
221226 <span >&ensp ; RushDB</span >
222227 </a >
223228 <div style =" display : flex ; align-items : center ; gap : 2rem " >
224- <button class =" nav-toggle" type =" button" aria-label =" 打开菜单 " @click =" toggleNavMenu" >
229+ <button class =" nav-toggle" type =" button" : aria-label =" t('nav.openMenu') " @click =" toggleNavMenu" >
225230 <span class =" nav-toggle-bars" aria-hidden =" true" ></span >
226231 </button >
227232 <ul class =" nav-links" >
228233 <li >
229- <a href =" #about" class =" lang-content lang-zh active" >关于我们</a ><a href =" #about" class =" lang-content lang-en" >About Us</a
230- ><a href =" #about" class =" lang-content lang-ja" >私たちについて</a >
234+ <a href =" #about" >{{ t("nav.about") }}</a >
231235 </li >
232236 <li >
233- <a href =" #achievements" class =" lang-content lang-zh active" >竞赛成就</a
234- ><a href =" #achievements" class =" lang-content lang-en" >Achievements</a
235- ><a href =" #achievements" class =" lang-content lang-ja" >競技成果</a >
237+ <a href =" #achievements" >{{ t("nav.achievements") }}</a >
236238 </li >
237239 <li >
238- <a href =" #projects" class =" lang-content lang-zh active" >项目作品</a ><a href =" #projects" class =" lang-content lang-en" >Projects</a
239- ><a href =" #projects" class =" lang-content lang-ja" >プロジェクト</a >
240+ <a href =" #projects" >{{ t("nav.projects") }}</a >
240241 </li >
241242 <li >
242- <a href =" #members" class =" lang-content lang-zh active" >团队成员</a ><a href =" #members" class =" lang-content lang-en" >Team Members</a
243- ><a href =" #members" class =" lang-content lang-ja" >チームメンバー</a >
243+ <a href =" #members" >{{ t("nav.members") }}</a >
244244 </li >
245245 <li >
246- <a href =" #news" class =" lang-content lang-zh active" >相关报道</a ><a href =" #news" class =" lang-content lang-en" >Related News</a
247- ><a href =" #news" class =" lang-content lang-ja" >関連報道</a >
246+ <a href =" #news" >{{ t("nav.news") }}</a >
248247 </li >
249248 <li >
250- <a href =" #contact" class =" lang-content lang-zh active" >联系我们</a ><a href =" #contact" class =" lang-content lang-en" >Contact Us</a
251- ><a href =" #contact" class =" lang-content lang-ja" >お問い合わせ</a >
249+ <a href =" #contact" >{{ t("nav.contact") }}</a >
252250 </li >
253251 </ul >
254252
255253 <div class =" language-switcher" :class =" { show: isLanguageOpen }" >
256254 <div class =" language-trigger" @click =" toggleLanguageSwitcher" >{{ languageLabel }}</div >
257255 <div class =" language-dropdown" >
258- <button class =" lang-btn active" data-lang =" zh" @click =" switchLanguage('zh')" >🇨🇳 中文</button >
259- <button class =" lang-btn" data-lang =" en" @click =" switchLanguage('en')" >🇬🇧 English</button >
260- <button class =" lang-btn" data-lang =" ja" @click =" switchLanguage('ja')" >🇯🇵 日本語</button >
256+ <button class =" lang-btn" :class =" { active: currentLang === 'zh' }" data-lang =" zh" @click =" switchLanguage('zh')" >
257+ {{ t("language.zh") }}
258+ </button >
259+ <button class =" lang-btn" :class =" { active: currentLang === 'en' }" data-lang =" en" @click =" switchLanguage('en')" >
260+ {{ t("language.en") }}
261+ </button >
262+ <button class =" lang-btn" :class =" { active: currentLang === 'ja' }" data-lang =" ja" @click =" switchLanguage('ja')" >
263+ {{ t("language.ja") }}
264+ </button >
261265 </div >
262266 </div >
263267 <a class =" nav-cta" href =" https://github.com/RushDB-Lab" target =" _blank" rel =" noopener noreferrer" >
264- <span class =" lang-content lang-zh active inline" >GitHub</span >
265- <span class =" lang-content lang-en inline" >GitHub</span >
266- <span class =" lang-content lang-ja inline" >GitHub</span >
268+ {{ t("nav.github") }}
267269 </a >
268270 </div >
269271 </div >
@@ -285,7 +287,7 @@ onUnmounted(() => {
285287
286288 <footer class =" footer" >
287289 <div class =" footer-content" >
288- <p class =" copyright" >© 2025 RushDB. All Rights Reserved. </p >
290+ <p class =" copyright" >{{ t("footer.copyright") }} </p >
289291 </div >
290292 </footer >
291293 </div >
0 commit comments