feat: locale system
This commit is contained in:
10
src/App.vue
10
src/App.vue
@@ -1,4 +1,12 @@
|
||||
<script lang="ts" setup></script>
|
||||
<script lang="ts" setup>
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useLanguageStore } from "./stores/LanguageStore";
|
||||
|
||||
onMounted(() => {
|
||||
// 加载 i18n
|
||||
useI18n().locale.value = useLanguageStore().language;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
<script setup lang="ts">
|
||||
import { useGlobalLanguageHook } from "@/hooks/globalLanguageHook";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
const { changeGlobalLanguage, curGlobalLanguage, optionalLanguages } =
|
||||
useGlobalLanguageHook();
|
||||
|
||||
const { locale, t } = useI18n();
|
||||
|
||||
const onClickChangeLocal = (newLanguage: string) => {
|
||||
changeGlobalLanguage(newLanguage, locale);
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -41,7 +48,7 @@ const { changeGlobalLanguage, curGlobalLanguage, optionalLanguages } =
|
||||
class="dropdown-content bg-base-200 text-base-content rounded-box top-px mt-14 w-56 overflow-y-auto border-[length:var(--border)] border-white/5 shadow-2xl outline-[length:var(--border)] outline-black/5"
|
||||
>
|
||||
<ul class="menu menu-sm w-full">
|
||||
<li class="menu-title text-xs">语言</li>
|
||||
<li class="menu-title text-xs">{{ t("nav.locale") }}</li>
|
||||
<li
|
||||
v-for="optionalLanguage in optionalLanguages"
|
||||
:key="optionalLanguage.label"
|
||||
@@ -50,7 +57,7 @@ const { changeGlobalLanguage, curGlobalLanguage, optionalLanguages } =
|
||||
:class="[
|
||||
curGlobalLanguage === optionalLanguage.label ? 'menu-active' : '',
|
||||
]"
|
||||
@click="changeGlobalLanguage(optionalLanguage.label)"
|
||||
@click="onClickChangeLocal(optionalLanguage.label)"
|
||||
>
|
||||
<span class="pe-4 font-mono font-bold opacity-40">
|
||||
{{ optionalLanguage.label }}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import { useGlobalThemeHook } from "@/hooks/globalThemeHook";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const { changeGlobalTheme, curGlobalTheme, optionalThemes } =
|
||||
useGlobalThemeHook();
|
||||
@@ -31,7 +34,7 @@ const { changeGlobalTheme, curGlobalTheme, optionalThemes } =
|
||||
tabindex="-1"
|
||||
class="dropdown-content bg-base-300 rounded-box z-1 w-52 p-2 shadow-2xl max-h-84 overflow-auto mt-6"
|
||||
>
|
||||
<li class="menu-title text-xs my-1">主题</li>
|
||||
<li class="menu-title text-xs my-1">{{ t("nav.theme") }}</li>
|
||||
<li
|
||||
v-for="optionalTheme in optionalThemes"
|
||||
:key="optionalTheme"
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import ChangeLanguageDropdownButton from "@/components/button/ChangeLanguageDropdownButton.vue";
|
||||
import ChangeThemeDropdownButton from "@/components/button/ChangeThemeDropdownButton.vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
const { t } = useI18n();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -27,16 +30,24 @@ import ChangeThemeDropdownButton from "@/components/button/ChangeThemeDropdownBu
|
||||
tabindex="-1"
|
||||
class="menu dropdown-content bg-base-100 rounded-box z-1 mt-5 w-52 p-2 shadow"
|
||||
>
|
||||
<li><a>首页</a></li>
|
||||
<li><a>关于</a></li>
|
||||
<li>
|
||||
<a>{{ t("nav.home") }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a>{{ t("nav.about") }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<a class="btn btn-ghost text-xl">daisyUI</a>
|
||||
<a class="btn btn-ghost text-xl">Hucky</a>
|
||||
</div>
|
||||
<div class="navbar-center hidden lg:flex">
|
||||
<ul class="menu menu-horizontal px-1">
|
||||
<li><a>首页</a></li>
|
||||
<li><a>关于</a></li>
|
||||
<li>
|
||||
<a>{{ t("nav.home") }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a>{{ t("nav.about") }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="navbar-end">
|
||||
|
||||
@@ -3,6 +3,7 @@ import {
|
||||
GlobalLanguage,
|
||||
languageMap,
|
||||
} from "@/stores/LanguageStore";
|
||||
import { Locale } from "vue-i18n";
|
||||
|
||||
const languageStore = useLanguageStore();
|
||||
|
||||
@@ -16,8 +17,12 @@ export const optionalLanguages = Object.entries(languageMap).map(
|
||||
// 一定不要通过改变 curGlobalLanguage 来改变语言,而要通过 changeGlobalLanguage 来改变语言
|
||||
const curGlobalLanguage = computed(() => languageStore.language);
|
||||
|
||||
function changeGlobalLanguage(language: GlobalLanguage) {
|
||||
function changeGlobalLanguage(
|
||||
language: GlobalLanguage,
|
||||
locale: WritableComputedRef<string>,
|
||||
) {
|
||||
languageStore.setLanguage(language);
|
||||
locale.value = language;
|
||||
}
|
||||
|
||||
export const useGlobalLanguageHook = () => ({
|
||||
|
||||
10
src/i18n/en_US.ts
Normal file
10
src/i18n/en_US.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { messagesInterface } from ".";
|
||||
|
||||
export const en_USMessages: messagesInterface = {
|
||||
nav: {
|
||||
home: "Home",
|
||||
about: "About",
|
||||
theme: "Theme",
|
||||
locale: "Locale",
|
||||
},
|
||||
};
|
||||
24
src/i18n/index.ts
Normal file
24
src/i18n/index.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { createI18n } from "vue-i18n";
|
||||
import { zh_CNMessages } from "./zh_CN";
|
||||
import { en_USMessages } from "./en_US";
|
||||
|
||||
export interface messagesInterface {
|
||||
nav: {
|
||||
home: string;
|
||||
about: string;
|
||||
theme: string;
|
||||
locale: string;
|
||||
};
|
||||
}
|
||||
|
||||
const i18n = createI18n({
|
||||
legacy: false,
|
||||
locale: "ZH",
|
||||
fallbackLocale: "EN",
|
||||
messages: {
|
||||
ZH: zh_CNMessages,
|
||||
EN: en_USMessages,
|
||||
},
|
||||
});
|
||||
|
||||
export default i18n;
|
||||
10
src/i18n/zh_CN.ts
Normal file
10
src/i18n/zh_CN.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { messagesInterface } from ".";
|
||||
|
||||
export const zh_CNMessages: messagesInterface = {
|
||||
nav: {
|
||||
home: "首页",
|
||||
about: "关于",
|
||||
theme: "主题",
|
||||
locale: "语言",
|
||||
},
|
||||
};
|
||||
@@ -2,10 +2,11 @@ import { createApp } from "vue";
|
||||
import "./style.css";
|
||||
import App from "./App.vue";
|
||||
import router from "./router";
|
||||
import i18n from "./i18n";
|
||||
import { createPinia } from "pinia";
|
||||
import piniaPluginPersistedstate from "pinia-plugin-persistedstate";
|
||||
|
||||
const pinia = createPinia();
|
||||
pinia.use(piniaPluginPersistedstate);
|
||||
|
||||
createApp(App).use(router).use(pinia).mount("#app");
|
||||
createApp(App).use(router).use(pinia).use(i18n).mount("#app");
|
||||
|
||||
Reference in New Issue
Block a user