i18n support

This commit is contained in:
KUN1007 2023-05-20 02:23:25 +08:00
parent 8a01d78829
commit 99f031f8ff
13 changed files with 279 additions and 54 deletions

146
package-lock.json generated
View file

@ -16,6 +16,7 @@
"axios": "^1.4.0",
"pinia": "^2.0.35",
"vue": "^3.2.47",
"vue-i18n": "^9.3.0-beta.17",
"vue-router": "^4.1.6"
},
"devDependencies": {
@ -425,6 +426,78 @@
"vue": ">=3"
}
},
"node_modules/@intlify/core-base": {
"version": "9.3.0-beta.17",
"resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.3.0-beta.17.tgz",
"integrity": "sha512-M/ZUU53G68YKN59E2gd/bOZB4TvFMWXvpWIgwsLJeAjktKYOt7JDSGdGHYGivKAG12pTGWeIeY6WmJCaDenloA==",
"dependencies": {
"@intlify/devtools-if": "9.3.0-beta.17",
"@intlify/message-compiler": "9.3.0-beta.17",
"@intlify/shared": "9.3.0-beta.17",
"@intlify/vue-devtools": "9.3.0-beta.17"
},
"engines": {
"node": ">= 14"
},
"funding": {
"url": "https://github.com/sponsors/kazupon"
}
},
"node_modules/@intlify/devtools-if": {
"version": "9.3.0-beta.17",
"resolved": "https://registry.npmjs.org/@intlify/devtools-if/-/devtools-if-9.3.0-beta.17.tgz",
"integrity": "sha512-up5vm1ytN9Wm/loKjFlp5TuDy7dmBVgU3UOk1vLUXUfYH+EMlm07pUXNiIpSjdt4Eak+bSLfsWcqPwhsb2jknw==",
"dependencies": {
"@intlify/shared": "9.3.0-beta.17"
},
"engines": {
"node": ">= 14"
},
"funding": {
"url": "https://github.com/sponsors/kazupon"
}
},
"node_modules/@intlify/message-compiler": {
"version": "9.3.0-beta.17",
"resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.3.0-beta.17.tgz",
"integrity": "sha512-i7hvVIRk1Ax2uKa9xLRJCT57to08OhFMhFXXjWN07rmx5pWQYQ23MfX1xgggv9drnWTNhqEiD+u4EJeHoS5+Ww==",
"dependencies": {
"@intlify/shared": "9.3.0-beta.17",
"source-map": "0.6.1"
},
"engines": {
"node": ">= 14"
},
"funding": {
"url": "https://github.com/sponsors/kazupon"
}
},
"node_modules/@intlify/shared": {
"version": "9.3.0-beta.17",
"resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.3.0-beta.17.tgz",
"integrity": "sha512-mscf7RQsUTOil35jTij4KGW1RC9SWQjYScwLxP53Ns6g24iEd5HN7ksbt9O6FvTmlQuX77u+MXpBdfJsGqizLQ==",
"engines": {
"node": ">= 14"
},
"funding": {
"url": "https://github.com/sponsors/kazupon"
}
},
"node_modules/@intlify/vue-devtools": {
"version": "9.3.0-beta.17",
"resolved": "https://registry.npmjs.org/@intlify/vue-devtools/-/vue-devtools-9.3.0-beta.17.tgz",
"integrity": "sha512-Wzl+3kZONjYG3lL8I8G+4H46s7m3CkxyoZXjZgC0zMy51cq1OTlOuOohcgxpwcSSYYVj9Y86PvlSakPNqHEweA==",
"dependencies": {
"@intlify/core-base": "9.3.0-beta.17",
"@intlify/shared": "9.3.0-beta.17"
},
"engines": {
"node": ">= 14"
},
"funding": {
"url": "https://github.com/sponsors/kazupon"
}
},
"node_modules/@jridgewell/gen-mapping": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
@ -2125,6 +2198,26 @@
"@vue/shared": "3.2.47"
}
},
"node_modules/vue-i18n": {
"version": "9.3.0-beta.17",
"resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.3.0-beta.17.tgz",
"integrity": "sha512-2r6QWgwCMjzpLb6RuIU8XPw8vU9kJu8OE4zGIOOnNq1gMYrzawO1LlK/yxG7ugWmzFA/IBqSIs6ADu0Z+PO/Ow==",
"dependencies": {
"@intlify/core-base": "9.3.0-beta.17",
"@intlify/shared": "9.3.0-beta.17",
"@intlify/vue-devtools": "9.3.0-beta.17",
"@vue/devtools-api": "^6.2.1"
},
"engines": {
"node": ">= 14"
},
"funding": {
"url": "https://github.com/sponsors/kazupon"
},
"peerDependencies": {
"vue": "^3.0.0"
}
},
"node_modules/vue-router": {
"version": "4.1.6",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.1.6.tgz",
@ -2407,6 +2500,48 @@
"@iconify/types": "^2.0.0"
}
},
"@intlify/core-base": {
"version": "9.3.0-beta.17",
"resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.3.0-beta.17.tgz",
"integrity": "sha512-M/ZUU53G68YKN59E2gd/bOZB4TvFMWXvpWIgwsLJeAjktKYOt7JDSGdGHYGivKAG12pTGWeIeY6WmJCaDenloA==",
"requires": {
"@intlify/devtools-if": "9.3.0-beta.17",
"@intlify/message-compiler": "9.3.0-beta.17",
"@intlify/shared": "9.3.0-beta.17",
"@intlify/vue-devtools": "9.3.0-beta.17"
}
},
"@intlify/devtools-if": {
"version": "9.3.0-beta.17",
"resolved": "https://registry.npmjs.org/@intlify/devtools-if/-/devtools-if-9.3.0-beta.17.tgz",
"integrity": "sha512-up5vm1ytN9Wm/loKjFlp5TuDy7dmBVgU3UOk1vLUXUfYH+EMlm07pUXNiIpSjdt4Eak+bSLfsWcqPwhsb2jknw==",
"requires": {
"@intlify/shared": "9.3.0-beta.17"
}
},
"@intlify/message-compiler": {
"version": "9.3.0-beta.17",
"resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.3.0-beta.17.tgz",
"integrity": "sha512-i7hvVIRk1Ax2uKa9xLRJCT57to08OhFMhFXXjWN07rmx5pWQYQ23MfX1xgggv9drnWTNhqEiD+u4EJeHoS5+Ww==",
"requires": {
"@intlify/shared": "9.3.0-beta.17",
"source-map": "0.6.1"
}
},
"@intlify/shared": {
"version": "9.3.0-beta.17",
"resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.3.0-beta.17.tgz",
"integrity": "sha512-mscf7RQsUTOil35jTij4KGW1RC9SWQjYScwLxP53Ns6g24iEd5HN7ksbt9O6FvTmlQuX77u+MXpBdfJsGqizLQ=="
},
"@intlify/vue-devtools": {
"version": "9.3.0-beta.17",
"resolved": "https://registry.npmjs.org/@intlify/vue-devtools/-/vue-devtools-9.3.0-beta.17.tgz",
"integrity": "sha512-Wzl+3kZONjYG3lL8I8G+4H46s7m3CkxyoZXjZgC0zMy51cq1OTlOuOohcgxpwcSSYYVj9Y86PvlSakPNqHEweA==",
"requires": {
"@intlify/core-base": "9.3.0-beta.17",
"@intlify/shared": "9.3.0-beta.17"
}
},
"@jridgewell/gen-mapping": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
@ -3678,6 +3813,17 @@
"@vue/shared": "3.2.47"
}
},
"vue-i18n": {
"version": "9.3.0-beta.17",
"resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.3.0-beta.17.tgz",
"integrity": "sha512-2r6QWgwCMjzpLb6RuIU8XPw8vU9kJu8OE4zGIOOnNq1gMYrzawO1LlK/yxG7ugWmzFA/IBqSIs6ADu0Z+PO/Ow==",
"requires": {
"@intlify/core-base": "9.3.0-beta.17",
"@intlify/shared": "9.3.0-beta.17",
"@intlify/vue-devtools": "9.3.0-beta.17",
"@vue/devtools-api": "^6.2.1"
}
},
"vue-router": {
"version": "4.1.6",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.1.6.tgz",

View file

@ -25,6 +25,7 @@
"axios": "^1.4.0",
"pinia": "^2.0.35",
"vue": "^3.2.47",
"vue-i18n": "^9.3.0-beta.17",
"vue-router": "^4.1.6"
},
"devDependencies": {

View file

@ -12,6 +12,11 @@ import router from '@/router'
// store
import { useSettingsPanelStore } from '@/store/modules/settings'
import { storeToRefs } from 'pinia'
// i18n
import { useI18n } from 'vue-i18n'
// i18n
const { t } = useI18n()
// store
const settingsStore = useSettingsPanelStore()
@ -82,7 +87,7 @@ onBeforeMount(() => {})
<div class="kungal-info">
<!-- 网站的名字和网站图标 -->
<img src="../assets/images/favicon.png" alt="KUNgal" />
<span>KUNGalgame</span>
<span>{{ t('header.name') }}</span>
</div>
<div class="top-bar">
<ul>
@ -114,19 +119,6 @@ onBeforeMount(() => {})
</template>
<style lang="less" scoped>
// .kungalgame-panel-enter-active,
// .kungalgame-panel-leave-active {
// transition: right 0.5s;
// }
// .kungalgame-panel-enter-from {
// right: -600px;
// }
// .kungalgame-panel-enter-to {
// right: 0;
// }
// .kungalgame-panel-leave-to {
// right: -600px;
// }
/* 头部样式 */
.header {
/* 头部高度 */

View file

@ -11,9 +11,31 @@ import { useSettingsPanelStore } from '@/store/modules/settings'
import { storeToRefs } from 'pinia'
// hook
import { useFixedLoli } from '@/hooks/useFixedLoli'
// hook
import { useLang } from '@/hooks/useLang'
// i18n
import { useI18n } from 'vue-i18n'
import { ref } from 'vue'
// 使 store
const settingsStore = useSettingsPanelStore()
//
const { kungalgameLang, setLang, initLang } = useLang()
const { t, locale } = useI18n({ useScope: 'global' })
//
initLang()
//
const changeLang = () => {
if (kungalgameLang.value === 'en') {
setLang('en')
locale.value = 'en'
kungalgameLang.value = 'zh'
} else {
setLang('zh')
locale.value = 'zh'
kungalgameLang.value = 'en'
}
}
// 使 hook
const { kungalgameLoliStatus, setLoli, initLoli, setLoliX, setLoliY } =
@ -22,7 +44,11 @@ const { kungalgameLoliStatus, setLoli, initLoli, setLoliX, setLoliY } =
//
initLoli()
let { showSettings } = storeToRefs(settingsStore)
// 使 store
const settingsStore = useSettingsPanelStore()
const { showSettings } = storeToRefs(settingsStore)
//
const handleClose = () => {
showSettings.value = false
}
@ -47,7 +73,14 @@ const handleClick = () => {
<div class="root">
<div class="container">
<div class="title">
<span>设置面板</span><Icon class="settings-icon" icon="uiw:setting-o" />
<span>设置面板</span>
<span
><Icon
class="change-lang"
icon="mdi:spoken-language"
@click="changeLang"
/></span>
<span><Icon class="settings-icon" icon="uiw:setting-o" /></span>
</div>
<div class="mode">
<!-- 白天 / 黑夜模式切换 -->
@ -126,6 +159,13 @@ const handleClick = () => {
display: flex;
justify-content: space-between;
align-items: center;
span {
display: flex;
align-items: center;
&:nth-child(2) {
cursor: pointer;
}
}
}
.settings-icon {
animation: settings 3s linear infinite;

View file

@ -1,45 +1,12 @@
// 导入 localStorage 中的面板数据
import {
getThemeStatus,
getMainPageWidth,
getBackgroundPicture,
getLoliStatus,
} from '@/utils/cache/local-storage'
import { type Ref, ref } from 'vue'
// 设置面板配置
interface KUNGalgameSettings {
// 是否显示设置面板
settings: boolean
// 是否黑夜模式
darkMode: Ref<boolean>
// 主页面宽度设置
pageWidth: Ref<number>
// 论坛背景设置0 为无背景
kungalgameBackground: Ref<number>
// 是否固定看板娘
fixLoli: Ref<boolean>
}
// 获取 localStorage 中的主题设置
const KUNGalgameTheme = ref<boolean>(getThemeStatus() || false)
// 获取 localeStorage 中的主页宽度设置
const KUNGalgameMainPageWidth = ref<number>(getMainPageWidth() || 61.8)
// 获取 localeStorage 中的背景图片设置
const KUNGalgameBackgroundPicture = ref<number>(getBackgroundPicture() || 61.8)
// 获取 localStorage 中的看板娘状态设置
const KUNGalgameLoliStatus = ref<boolean>(getLoliStatus() || false)
const kungalgameSettings: KUNGalgameSettings = {
// false -> settings panel off, true -> settings panel on
settings: false,
darkMode: KUNGalgameTheme,
pageWidth: KUNGalgameMainPageWidth,
kungalgameBackground: KUNGalgameBackgroundPicture || 0,
fixLoli: KUNGalgameLoliStatus || true,
}
export default kungalgameSettings

26
src/hooks/useLang.ts Normal file
View file

@ -0,0 +1,26 @@
// 钩子函数,网站显示语言
import { ref, watchEffect } from 'vue'
import { getLangStatus, setLangStatus } from '@/utils/cache/local-storage'
// 初始化 KUNGalgame 语言设置true 为中文
const kungalgameLang = ref<string>(getLangStatus() || 'true')
const setLang = (status: string) => {
kungalgameLang.value = status
}
const initLang = () => {
watchEffect(() => {
setLangStatus(kungalgameLang.value)
})
}
// 全局 hook
export function useLang() {
return {
kungalgameLang,
setLang,
initLang,
}
}

5
src/language/en.ts Normal file
View file

@ -0,0 +1,5 @@
export default {
header: {
name: 'KUNGalgame',
},
}

19
src/language/i18n.ts Normal file
View file

@ -0,0 +1,19 @@
import { createI18n } from 'vue-i18n'
import zh from './zh'
import en from './en'
const i18n = createI18n({
locale: 'en',
// locale: 'zh',
// 支持 Vue3 composition API
legacy: false,
// 全局注册 ts 方法
globalInjection: true,
messages: {
zh,
en,
},
})
export default i18n

5
src/language/zh.ts Normal file
View file

@ -0,0 +1,5 @@
export default {
header: {
name: '鲲站',
},
}

View file

@ -6,8 +6,10 @@ import App from './App.vue'
import router from './router'
/* 引入 Pinia */
import { createPinia } from 'pinia'
// 入 css 动画
// 入 css 动画
import 'animate.css'
// 引入 i18n
import i18n from '@/language/i18n'
/* 导入 Pinia */
const store = createPinia()
@ -15,4 +17,4 @@ const store = createPinia()
// css
import '@/styles/reset.css'
import '@/styles/theme/theme.less'
createApp(App).use(router).use(store).mount('#app')
createApp(App).use(router).use(store).use(i18n).mount('#app')

View file

@ -4,6 +4,8 @@ const KUN = 'KUNGalgame'
// KUNGalgame 的 cache 键
class KUNCacheKey {
// 中文 / 英文
static MAIN_LANG = `${KUN}-lang`
// 白天 / 黑夜模式
static THEME_STATUS = `${KUN}-theme`
// 主页的宽度

View file

@ -3,6 +3,19 @@
// 引入定义的键
import KUNCacheKey from './cache-key'
/*
* KUNGalgame
*/
export const getLangStatus = () => {
return localStorage.getItem(KUNCacheKey.MAIN_LANG) as string
}
export const setLangStatus = (lang: string) => {
// true -> chinese, false -> english
localStorage.setItem(KUNCacheKey.MAIN_LANG, lang)
}
export const getThemeStatus = () => {
return localStorage.getItem(KUNCacheKey.THEME_STATUS)
}
@ -27,6 +40,10 @@ export const setBackgroundPicture = (backgroundPicture: string) => {
return localStorage.setItem(KUNCacheKey.BACKGROUND_PICTURE, backgroundPicture)
}
/*
* KUNGalgame
*/
// 将 localeStorage 中的字符串看板娘状态转换为布尔值返回
export const getLoliStatus = () => {
return localStorage.getItem(KUNCacheKey.LOLI_STATUS) as string

3
src/utils/http.ts Normal file
View file

@ -0,0 +1,3 @@
// 封装 axios