Skip to content

Commit 1cbf17d

Browse files
committed
refactor: use vue-i18
1 parent fdd1b2a commit 1cbf17d

File tree

12 files changed

+695
-346
lines changed

12 files changed

+695
-346
lines changed

package-lock.json

Lines changed: 67 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
"typecheck": "vue-tsc --noEmit"
1212
},
1313
"dependencies": {
14-
"vue": "^3.5.13"
14+
"vue": "^3.5.13",
15+
"vue-i18n": "^9.10.2"
1516
},
1617
"devDependencies": {
1718
"@types/node": "^22.10.2",

src/App.vue

Lines changed: 39 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
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
45
import AboutSection from "./sections/AboutSection.vue";
56
import AchievementsSection from "./sections/AchievementsSection.vue";
@@ -9,16 +10,21 @@ import MembersSection from "./sections/MembersSection.vue";
910
import NewsSection from "./sections/NewsSection.vue";
1011
import 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+
});
1523
const isLanguageOpen = ref(false);
1624
const isMenuOpen = ref(false);
1725
1826
const 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
2430
const 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
6664
async 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
9794
function 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+
205210
onUnmounted(() => {
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

Comments
 (0)