i18n support
This commit is contained in:
parent
8a01d78829
commit
99f031f8ff
146
package-lock.json
generated
146
package-lock.json
generated
|
@ -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",
|
||||
|
|
|
@ -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": {
|
||||
|
|
|
@ -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 {
|
||||
/* 头部高度 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
26
src/hooks/useLang.ts
Normal 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
5
src/language/en.ts
Normal file
|
@ -0,0 +1,5 @@
|
|||
export default {
|
||||
header: {
|
||||
name: 'KUNGalgame',
|
||||
},
|
||||
}
|
19
src/language/i18n.ts
Normal file
19
src/language/i18n.ts
Normal 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
5
src/language/zh.ts
Normal file
|
@ -0,0 +1,5 @@
|
|||
export default {
|
||||
header: {
|
||||
name: '鲲站',
|
||||
},
|
||||
}
|
|
@ -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')
|
||||
|
|
2
src/utils/cache/cache-key.ts
vendored
2
src/utils/cache/cache-key.ts
vendored
|
@ -4,6 +4,8 @@ const KUN = 'KUNGalgame'
|
|||
|
||||
// KUNGalgame 的 cache 键
|
||||
class KUNCacheKey {
|
||||
// 中文 / 英文
|
||||
static MAIN_LANG = `${KUN}-lang`
|
||||
// 白天 / 黑夜模式
|
||||
static THEME_STATUS = `${KUN}-theme`
|
||||
// 主页的宽度
|
||||
|
|
17
src/utils/cache/local-storage.ts
vendored
17
src/utils/cache/local-storage.ts
vendored
|
@ -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
3
src/utils/http.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
// 封装 axios
|
||||
|
||||
|
Loading…
Reference in a new issue