feat(i18n): set up vue-i18n with dynamic locale loading

This commit is contained in:
ghostubborn
2026-04-01 15:22:14 +08:00
parent 0c18e1aeca
commit 22bf50f877
6 changed files with 103 additions and 1 deletions

View File

@@ -1,5 +1,5 @@
<!doctype html>
<html lang="zh-CN">
<html lang="zh">
<head>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

View File

@@ -11,6 +11,7 @@
"axios": "^1.13.2",
"d3": "^7.9.0",
"vue": "^3.5.24",
"vue-i18n": "^9.14.5",
"vue-router": "^4.6.3"
},
"devDependencies": {
@@ -506,6 +507,50 @@
"node": ">=18"
}
},
"node_modules/@intlify/core-base": {
"version": "9.14.5",
"resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.14.5.tgz",
"integrity": "sha512-5ah5FqZG4pOoHjkvs8mjtv+gPKYU0zCISaYNjBNNqYiaITxW8ZtVih3GS/oTOqN8d9/mDLyrjD46GBApNxmlsA==",
"license": "MIT",
"dependencies": {
"@intlify/message-compiler": "9.14.5",
"@intlify/shared": "9.14.5"
},
"engines": {
"node": ">= 16"
},
"funding": {
"url": "https://github.com/sponsors/kazupon"
}
},
"node_modules/@intlify/message-compiler": {
"version": "9.14.5",
"resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.14.5.tgz",
"integrity": "sha512-IHzgEu61/YIpQV5Pc3aRWScDcnFKWvQA9kigcINcCBXN8mbW+vk9SK+lDxA6STzKQsVJxUPg9ACC52pKKo3SVQ==",
"license": "MIT",
"dependencies": {
"@intlify/shared": "9.14.5",
"source-map-js": "^1.0.2"
},
"engines": {
"node": ">= 16"
},
"funding": {
"url": "https://github.com/sponsors/kazupon"
}
},
"node_modules/@intlify/shared": {
"version": "9.14.5",
"resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.14.5.tgz",
"integrity": "sha512-9gB+E53BYuAEMhbCAxVgG38EZrk59sxBtv3jSizNL2hEWlgjBjAw1AwpLHtNaeda12pe6W20OGEa0TwuMSRbyQ==",
"license": "MIT",
"engines": {
"node": ">= 16"
},
"funding": {
"url": "https://github.com/sponsors/kazupon"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.5.5",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
@@ -2035,6 +2080,27 @@
}
}
},
"node_modules/vue-i18n": {
"version": "9.14.5",
"resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.14.5.tgz",
"integrity": "sha512-0jQ9Em3ymWngyiIkj0+c/k7WgaPO+TNzjKSNq9BvBQaKJECqn9cd9fL4tkDhB5G1QBskGl9YxxbDAhgbFtpe2g==",
"deprecated": "v9 and v10 no longer supported. please migrate to v11. about maintenance status, see https://vue-i18n.intlify.dev/guide/maintenance.html",
"license": "MIT",
"dependencies": {
"@intlify/core-base": "9.14.5",
"@intlify/shared": "9.14.5",
"@vue/devtools-api": "^6.5.0"
},
"engines": {
"node": ">= 16"
},
"funding": {
"url": "https://github.com/sponsors/kazupon"
},
"peerDependencies": {
"vue": "^3.0.0"
}
},
"node_modules/vue-router": {
"version": "4.6.3",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.6.3.tgz",

View File

@@ -12,6 +12,7 @@
"axios": "^1.13.2",
"d3": "^7.9.0",
"vue": "^3.5.24",
"vue-i18n": "^9.14.5",
"vue-router": "^4.6.3"
},
"devDependencies": {

View File

@@ -0,0 +1,27 @@
import { createI18n } from 'vue-i18n'
import languages from '../../../locales/languages.json'
const localeFiles = import.meta.glob('../../../locales/!(languages).json', { eager: true })
const messages = {}
const availableLocales = []
for (const path in localeFiles) {
const key = path.match(/\/([^/]+)\.json$/)[1]
if (languages[key]) {
messages[key] = localeFiles[path].default
availableLocales.push({ key, label: languages[key].label })
}
}
const savedLocale = localStorage.getItem('locale') || 'zh'
const i18n = createI18n({
legacy: false,
locale: savedLocale,
fallbackLocale: 'zh',
messages
})
export { availableLocales }
export default i18n

View File

@@ -1,9 +1,11 @@
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import i18n from './i18n'
const app = createApp(App)
app.use(router)
app.use(i18n)
app.mount('#app')

View File

@@ -1,9 +1,15 @@
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
// https://vite.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@locales': path.resolve(__dirname, '../locales')
}
},
server: {
port: 3000,
open: true,