From 2ce76820dab5594afc06fc5fa57c661d1d88f277 Mon Sep 17 00:00:00 2001 From: molong Date: Wed, 14 Jan 2026 12:14:32 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BC=95=E5=85=A5=E8=AF=AD=E8=A8=80=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useI18n.js | 16 +++ src/i18n/index.js | 15 +++ src/i18n/locales/en-US.js | 103 ++++++++++++++++++++ src/i18n/locales/zh-CN.js | 103 ++++++++++++++++++++ src/layouts/components/LanguageSwitcher.vue | 91 +++++++++++++++++ src/main.js | 7 ++ src/pages/login/index.vue | 40 +++++--- src/stores/modules/i18n.js | 34 +++++++ vite.config.js | 18 ++-- 9 files changed, 406 insertions(+), 21 deletions(-) create mode 100644 src/hooks/useI18n.js create mode 100644 src/i18n/index.js create mode 100644 src/i18n/locales/en-US.js create mode 100644 src/i18n/locales/zh-CN.js create mode 100644 src/layouts/components/LanguageSwitcher.vue create mode 100644 src/stores/modules/i18n.js diff --git a/src/hooks/useI18n.js b/src/hooks/useI18n.js new file mode 100644 index 0000000..ef0f6fa --- /dev/null +++ b/src/hooks/useI18n.js @@ -0,0 +1,16 @@ +import { useI18n as useVueI18n } from 'vue-i18n' +import { useI18nStore } from '@/stores/modules/i18n' + +export function useI18n() { + const { t, locale, availableLocales } = useVueI18n() + const i18nStore = useI18nStore() + + return { + t, + locale, + availableLocales, + setLocale: i18nStore.setLocale, + currentLocale: i18nStore.currentLocale, + localeLabel: i18nStore.localeLabel + } +} diff --git a/src/i18n/index.js b/src/i18n/index.js new file mode 100644 index 0000000..686b68a --- /dev/null +++ b/src/i18n/index.js @@ -0,0 +1,15 @@ +import { createI18n } from 'vue-i18n' +import zh from './locales/zh-CN' +import en from './locales/en-US' + +const i18n = createI18n({ + legacy: false, + locale: 'zh-CN', + fallbackLocale: 'en-US', + messages: { + 'zh-CN': zh, + 'en-US': en + } +}) + +export default i18n diff --git a/src/i18n/locales/en-US.js b/src/i18n/locales/en-US.js new file mode 100644 index 0000000..0a1ef77 --- /dev/null +++ b/src/i18n/locales/en-US.js @@ -0,0 +1,103 @@ +export default { + common: { + welcome: 'Welcome', + login: 'Login', + logout: 'Logout', + register: 'Register', + username: 'Username', + password: 'Password', + confirmPassword: 'Confirm Password', + email: 'Email', + phone: 'Phone', + rememberMe: 'Remember Me', + forgotPassword: 'Forgot Password?', + submit: 'Submit', + cancel: 'Cancel', + save: 'Save', + edit: 'Edit', + delete: 'Delete', + add: 'Add', + search: 'Search', + reset: 'Reset', + confirm: 'Confirm', + back: 'Back', + next: 'Next', + previous: 'Previous', + refresh: 'Refresh', + export: 'Export', + import: 'Import', + download: 'Download', + upload: 'Upload', + view: 'View', + detail: 'Detail', + settings: 'Settings', + profile: 'Profile', + language: 'Language', + theme: 'Theme', + dark: 'Dark', + light: 'Light', + loading: 'Loading...', + noData: 'No Data', + success: 'Operation Successful', + error: 'Operation Failed', + warning: 'Warning', + info: 'Info', + confirmDelete: 'Are you sure you want to delete?', + confirmLogout: 'Are you sure you want to logout?', + required: 'This field is required', + operation: 'Operation', + time: 'Time', + status: 'Status', + enabled: 'Enabled', + disabled: 'Disabled', + yes: 'Yes', + no: 'No' + }, + menu: { + dashboard: 'Dashboard', + userManagement: 'User Management', + roleManagement: 'Role Management', + permissionManagement: 'Permission Management', + systemSettings: 'System Settings', + logManagement: 'Log Management' + }, + login: { + title: 'User Login', + subtitle: 'Welcome back, please login to your account', + loginButton: 'Login', + loginSuccess: 'Login Successful', + loginFailed: 'Login Failed', + usernamePlaceholder: 'Please enter username', + passwordPlaceholder: 'Please enter password', + noAccount: "Don't have an account?", + registerNow: 'Register Now' + }, + layout: { + toggleSidebar: 'Toggle Sidebar', + collapse: 'Collapse', + expand: 'Expand', + logout: 'Logout' + }, + table: { + total: 'Total {total} items', + selected: '{selected} items selected', + actions: 'Actions', + noData: 'No Data', + sort: 'Sort', + filter: 'Filter' + }, + pagination: { + goTo: 'Go to', + page: 'Page', + total: 'Total {total} items', + itemsPerPage: '{size} items per page' + }, + form: { + required: 'This field is required', + invalidEmail: 'Please enter a valid email address', + invalidPhone: 'Please enter a valid phone number', + passwordMismatch: 'Passwords do not match', + minLength: 'Minimum {min} characters required', + maxLength: 'Maximum {max} characters allowed' + } +} diff --git a/src/i18n/locales/zh-CN.js b/src/i18n/locales/zh-CN.js new file mode 100644 index 0000000..c86871d --- /dev/null +++ b/src/i18n/locales/zh-CN.js @@ -0,0 +1,103 @@ +export default { + common: { + welcome: '欢迎使用', + login: '登录', + logout: '退出登录', + register: '注册', + username: '用户名', + password: '密码', + confirmPassword: '确认密码', + email: '邮箱', + phone: '手机号', + rememberMe: '记住我', + forgotPassword: '忘记密码?', + submit: '提交', + cancel: '取消', + save: '保存', + edit: '编辑', + delete: '删除', + add: '添加', + search: '搜索', + reset: '重置', + confirm: '确认', + back: '返回', + next: '下一步', + previous: '上一步', + refresh: '刷新', + export: '导出', + import: '导入', + download: '下载', + upload: '上传', + view: '查看', + detail: '详情', + settings: '设置', + profile: '个人资料', + language: '语言', + theme: '主题', + dark: '暗色', + light: '亮色', + loading: '加载中...', + noData: '暂无数据', + success: '操作成功', + error: '操作失败', + warning: '警告', + info: '提示', + confirmDelete: '确定要删除吗?', + confirmLogout: '确定要退出登录吗?', + required: '此项为必填项', + operation: '操作', + time: '时间', + status: '状态', + enabled: '启用', + disabled: '禁用', + yes: '是', + no: '否' + }, + menu: { + dashboard: '仪表板', + userManagement: '用户管理', + roleManagement: '角色管理', + permissionManagement: '权限管理', + systemSettings: '系统设置', + logManagement: '日志管理' + }, + login: { + title: '用户登录', + subtitle: '欢迎回来,请登录您的账户', + loginButton: '登录', + loginSuccess: '登录成功', + loginFailed: '登录失败', + usernamePlaceholder: '请输入用户名', + passwordPlaceholder: '请输入密码', + noAccount: '还没有账户?', + registerNow: '立即注册' + }, + layout: { + toggleSidebar: '切换侧边栏', + collapse: '折叠', + expand: '展开', + logout: '退出登录' + }, + table: { + total: '共 {total} 条', + selected: '已选择 {selected} 项', + actions: '操作', + noData: '暂无数据', + sort: '排序', + filter: '筛选' + }, + pagination: { + goTo: '前往', + page: '页', + total: '共 {total} 条', + itemsPerPage: '每页 {size} 条' + }, + form: { + required: '此项为必填项', + invalidEmail: '请输入有效的邮箱地址', + invalidPhone: '请输入有效的手机号', + passwordMismatch: '两次输入的密码不一致', + minLength: '最少需要 {min} 个字符', + maxLength: '最多允许 {max} 个字符' + } +} diff --git a/src/layouts/components/LanguageSwitcher.vue b/src/layouts/components/LanguageSwitcher.vue new file mode 100644 index 0000000..698ad93 --- /dev/null +++ b/src/layouts/components/LanguageSwitcher.vue @@ -0,0 +1,91 @@ + + + + + diff --git a/src/main.js b/src/main.js index c934821..1082a3a 100644 --- a/src/main.js +++ b/src/main.js @@ -3,10 +3,17 @@ import { createApp } from 'vue' import App from './App.vue' import router from './router' import pinia from './stores' +import i18n from './i18n' +import { useI18nStore } from './stores/modules/i18n' const app = createApp(App) app.use(router) app.use(pinia) +app.use(i18n) + +// 初始化 i18n store,从 localStorage 读取保存的语言设置 +const i18nStore = useI18nStore() +i18nStore.initLocale() app.mount('#app') diff --git a/src/pages/login/index.vue b/src/pages/login/index.vue index 5160d2c..6fdef84 100644 --- a/src/pages/login/index.vue +++ b/src/pages/login/index.vue @@ -1,5 +1,9 @@