国际化、主题处理

This commit is contained in:
Gary Fu
2023-12-16 21:05:00 +08:00
parent ffb209c494
commit 99629bc0a5
9 changed files with 184 additions and 49 deletions

144
package-lock.json generated
View File

@@ -9,10 +9,12 @@
"version": "0.0.0",
"dependencies": {
"@element-plus/icons-vue": "^2.1.0",
"@vueuse/core": "^10.7.0",
"dayjs": "^1.11.8",
"element-plus": "^2.3.4",
"lodash": "^4.17.21",
"pinia": "^2.0.32",
"pinia-plugin-persistedstate": "^3.2.0",
"vue": "^3.2.47",
"vue-i18n": "^9.2.2",
"vue-router": "^4.1.6"
@@ -635,9 +637,9 @@
}
},
"node_modules/@types/web-bluetooth": {
"version": "0.0.16",
"resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz",
"integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ=="
"version": "0.0.20",
"resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz",
"integrity": "sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow=="
},
"node_modules/@vitejs/plugin-vue": {
"version": "4.2.1",
@@ -778,23 +780,23 @@
"integrity": "sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ=="
},
"node_modules/@vueuse/core": {
"version": "9.13.0",
"resolved": "https://registry.npmjs.org/@vueuse/core/-/core-9.13.0.tgz",
"integrity": "sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==",
"version": "10.7.0",
"resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.7.0.tgz",
"integrity": "sha512-4EUDESCHtwu44ZWK3Gc/hZUVhVo/ysvdtwocB5vcauSV4B7NiGY5972WnsojB3vRNdxvAt7kzJWE2h9h7C9d5w==",
"dependencies": {
"@types/web-bluetooth": "^0.0.16",
"@vueuse/metadata": "9.13.0",
"@vueuse/shared": "9.13.0",
"vue-demi": "*"
"@types/web-bluetooth": "^0.0.20",
"@vueuse/metadata": "10.7.0",
"@vueuse/shared": "10.7.0",
"vue-demi": ">=0.14.6"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@vueuse/core/node_modules/vue-demi": {
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.0.tgz",
"integrity": "sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg==",
"version": "0.14.6",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz",
"integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==",
"hasInstallScript": true,
"bin": {
"vue-demi-fix": "bin/vue-demi-fix.js",
@@ -817,28 +819,28 @@
}
},
"node_modules/@vueuse/metadata": {
"version": "9.13.0",
"resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.13.0.tgz",
"integrity": "sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==",
"version": "10.7.0",
"resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.7.0.tgz",
"integrity": "sha512-GlaH7tKP2iBCZ3bHNZ6b0cl9g0CJK8lttkBNUX156gWvNYhTKEtbweWLm9rxCPIiwzYcr/5xML6T8ZUEt+DkvA==",
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@vueuse/shared": {
"version": "9.13.0",
"resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-9.13.0.tgz",
"integrity": "sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==",
"version": "10.7.0",
"resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.7.0.tgz",
"integrity": "sha512-kc00uV6CiaTdc3i1CDC4a3lBxzaBE9AgYNtFN87B5OOscqeWElj/uza8qVDmk7/U8JbqoONLbtqiLJ5LGRuqlw==",
"dependencies": {
"vue-demi": "*"
"vue-demi": ">=0.14.6"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@vueuse/shared/node_modules/vue-demi": {
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.0.tgz",
"integrity": "sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg==",
"version": "0.14.6",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz",
"integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==",
"hasInstallScript": true,
"bin": {
"vue-demi-fix": "bin/vue-demi-fix.js",
@@ -1217,6 +1219,94 @@
"vue": "^3.2.0"
}
},
"node_modules/element-plus/node_modules/@types/web-bluetooth": {
"version": "0.0.16",
"resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz",
"integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ=="
},
"node_modules/element-plus/node_modules/@vueuse/core": {
"version": "9.13.0",
"resolved": "https://registry.npmjs.org/@vueuse/core/-/core-9.13.0.tgz",
"integrity": "sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==",
"dependencies": {
"@types/web-bluetooth": "^0.0.16",
"@vueuse/metadata": "9.13.0",
"@vueuse/shared": "9.13.0",
"vue-demi": "*"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/element-plus/node_modules/@vueuse/core/node_modules/vue-demi": {
"version": "0.14.6",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz",
"integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==",
"hasInstallScript": true,
"bin": {
"vue-demi-fix": "bin/vue-demi-fix.js",
"vue-demi-switch": "bin/vue-demi-switch.js"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"@vue/composition-api": "^1.0.0-rc.1",
"vue": "^3.0.0-0 || ^2.6.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/element-plus/node_modules/@vueuse/metadata": {
"version": "9.13.0",
"resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.13.0.tgz",
"integrity": "sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==",
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/element-plus/node_modules/@vueuse/shared": {
"version": "9.13.0",
"resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-9.13.0.tgz",
"integrity": "sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==",
"dependencies": {
"vue-demi": "*"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/element-plus/node_modules/@vueuse/shared/node_modules/vue-demi": {
"version": "0.14.6",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz",
"integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==",
"hasInstallScript": true,
"bin": {
"vue-demi-fix": "bin/vue-demi-fix.js",
"vue-demi-switch": "bin/vue-demi-switch.js"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"@vue/composition-api": "^1.0.0-rc.1",
"vue": "^3.0.0-0 || ^2.6.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/es-abstract": {
"version": "1.21.2",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.2.tgz",
@@ -2792,6 +2882,14 @@
}
}
},
"node_modules/pinia-plugin-persistedstate": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/pinia-plugin-persistedstate/-/pinia-plugin-persistedstate-3.2.0.tgz",
"integrity": "sha512-tZbNGf2vjAQcIm7alK40sE51Qu/m9oWr+rEgNm/2AWr1huFxj72CjvpQcIQzMknDBJEkQznCLAGtJTIcLKrKdw==",
"peerDependencies": {
"pinia": "^2.0.0"
}
},
"node_modules/pinia/node_modules/vue-demi": {
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.0.tgz",

View File

@@ -10,10 +10,12 @@
},
"dependencies": {
"@element-plus/icons-vue": "^2.1.0",
"@vueuse/core": "^10.7.0",
"dayjs": "^1.11.8",
"element-plus": "^2.3.4",
"lodash": "^4.17.21",
"pinia": "^2.0.32",
"pinia-plugin-persistedstate": "^3.2.0",
"vue": "^3.2.47",
"vue-i18n": "^9.2.2",
"vue-router": "^4.1.6"

View File

@@ -1,9 +1,13 @@
<script setup>
import { useGlobalConfigStore } from '@/stores/globalConfig'
import { $changeLocale, elementLocale } from '@/languages/MessagesConfig'
const globalConfigStore = useGlobalConfigStore()
$changeLocale(globalConfigStore.currentLocale)
</script>
<template>
<el-config-provider :locale="$currentLocale.localeData">
<el-config-provider :locale="elementLocale.localeData">
<router-view />
</el-config-provider>
</template>

View File

@@ -1,6 +1,11 @@
<script setup>
import { ref } from 'vue'
import { useDark } from '@vueuse/core'
import { Check } from '@element-plus/icons-vue'
import { useGlobalConfigStore } from '@/stores/globalConfig'
const globalConfigStore = useGlobalConfigStore()
const isCollapseLeft = ref(false)
@@ -10,6 +15,8 @@ const updateCollapseLeft = () => {
emit('update:collapseLeft', isCollapseLeft.value)
}
const isDark = useDark()
defineProps({
collapseLeft: {
type: Boolean
@@ -41,12 +48,18 @@ defineProps({
index="1-1"
@click="$changeLocale('zh-CN')"
>
<el-icon v-if="globalConfigStore.currentLocale==='zh-CN'">
<Check />
</el-icon>
{{ $t('common.label.langCn') }}
</el-menu-item>
<el-menu-item
index="1-2"
@click="$changeLocale('en-US')"
>
<el-icon v-if="globalConfigStore.currentLocale==='en-US'">
<Check />
</el-icon>
{{ $t('common.label.langEn') }}
</el-menu-item>
</el-sub-menu>
@@ -54,15 +67,24 @@ defineProps({
<template #title>
{{ $t('common.label.theme') }}
</template>
<el-menu-item index="2-1">
<el-menu-item
index="2-1"
@click="isDark=false"
>
<el-icon v-if="!isDark">
<Check />
</el-icon>
{{ $t('common.label.themeDefault') }}
</el-menu-item>
<el-menu-item index="2-2">
<el-menu-item
index="2-2"
@click="isDark=true"
>
<el-icon v-if="isDark">
<Check />
</el-icon>
{{ $t('common.label.themeDark') }}
</el-menu-item>
<el-menu-item index="2-3">
{{ $t('common.label.themePurple') }}
</el-menu-item>
</el-sub-menu>
<el-sub-menu index="3">
<template #title>

View File

@@ -1,11 +1,12 @@
import { createI18n } from 'vue-i18n'
import { reactive } from 'vue'
import { ref } from 'vue'
import messagesCn from './messages_cn'
import messagesEn from './messages_en'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import en from 'element-plus/dist/locale/en.mjs'
import 'dayjs/locale/zh-cn'
import dayjs from 'dayjs'
import { useGlobalConfigStore } from '@/stores/globalConfig'
const DEFAULT_LOCALE = 'zh-CN'
dayjs.locale(DEFAULT_LOCALE) // dayjs的语言配置
@@ -20,20 +21,20 @@ const i18n = createI18n({
} // set locale messages
})
const $currentLocale = reactive({ // 用于element-plus
export const elementLocale = ref({ // 用于element-plus
localeData: zhCn
})
const $changeLocale = function (locale) {
this.$i18n.locale = locale
this.$currentLocale.localeData = locale === DEFAULT_LOCALE ? zhCn : en
export const $changeLocale = function (locale) {
i18n.global.locale.value = locale
elementLocale.value.localeData = locale === DEFAULT_LOCALE ? zhCn : en
dayjs.locale(locale.toLowerCase())
useGlobalConfigStore().changeLocale(locale)
}
export default {
install (app) {
app.use(i18n)
app.config.globalProperties.$currentLocale = $currentLocale
app.config.globalProperties.$changeLocale = $changeLocale
}
}

View File

@@ -1,8 +1,9 @@
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import 'element-plus/theme-chalk/dark/css-vars.css'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import { usePinia } from '@/store'
import messagesConfig from '@/languages/MessagesConfig'
@@ -13,7 +14,7 @@ import './assets/main.css'
const app = createApp(App)
app.use(createPinia())
app.use(usePinia)
app.use(router)
app.use(ElementPlus)
app.use(messagesConfig)

17
src/store.js Normal file
View File

@@ -0,0 +1,17 @@
import { defineStore, createPinia } from 'pinia'
import piniaPluginPersistedState from 'pinia-plugin-persistedstate'
import { useGlobalConfigStore } from '@/stores/globalConfig'
export const usePinia = {
install (app) {
const pinia = createPinia()
pinia.use(piniaPluginPersistedState)
app.use(pinia)
return pinia
}
}
export const useStore = defineStore('store', () => {
return {
globalConfig: useGlobalConfigStore()
}
})

View File

@@ -1,12 +0,0 @@
import { ref, computed } from 'vue'
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', () => {
const count = ref(0)
const doubleCount = computed(() => count.value * 2)
function increment() {
count.value++
}
return { count, doubleCount, increment }
})

View File

@@ -7,4 +7,6 @@ export const useGlobalConfigStore = defineStore('globalConfig', () => {
currentLocale.value = locale
}
return { currentLocale, changeLocale }
}, {
persist: true
})