forked from mengyxu/noob-components
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
7.4 KiB
7.4 KiB
I18n
Internationalization using vue3-i18n with class-based translation modules.
Overview
The i18n system uses vue3-i18n with class-based translation modules for English and Chinese. Translations are organized by domain into flat object structures.
Architecture
I18n Module
├── vue3-i18n instance (i18n)
├── Zh class (Chinese translations)
├── En class (English translations)
├── registerLang() - dynamic language registration
└── createt() - namespace suffix helper
I18n Setup
File: /home/hechang27/Documents/sprt/noob-components/plugs/i18n/index.ts
import { createI18n } from 'vue3-i18n';
import Zh from './zh';
import En from './en';
const messages = {
zh: new Zh(),
en: new En(),
};
const i18n = createI18n({
locale: 'zh',
messages,
});
const registerLang = (name, data) => {
messages[name] = data;
};
export { i18n, Zh, En, registerLang };
export const createt = (sufix: string) => {
return (key: string): string => {
key = sufix + key;
return i18n.t(key);
};
};
Key Exports
| Export | Type | Description |
|---|---|---|
i18n |
VueI18n | Main i18n instance |
Zh |
class | Chinese translation class |
En |
class | English translation class |
registerLang |
function | Dynamically register new language |
createt |
function | Creates namespace-prefixed translator |
Translation Structure
Translations are organized by domain with flat object keys:
Base Translations (common actions)
English (plugs/i18n/en.ts):
base = {
color: 'Color',
add: 'Add',
delete: 'Delete',
modify: 'Modify',
stop: 'Stop',
select: 'Select',
refresh: 'Refresh',
save: 'Save',
confirm: 'Confirm',
cancel: 'Cancel',
loading: 'Loading...',
active: 'Active',
inactive: 'Inactive',
key: 'Key',
value: 'Value',
import: 'Import',
export: 'Export',
};
Chinese (plugs/i18n/zh.ts):
base = {
color: '颜色',
add: '添加',
delete: '删除',
modify: '修改',
stop: '停止',
select: '查询',
refresh: '刷新',
save: '保存',
confirm: '确认',
cancel: '取消',
loading: '加载中...',
active: '生效',
inactive: '无效',
key: '键',
value: '值',
import: '导入',
export: '导出',
};
Domain Keys
Styles
English:
styles = ['Default', 'Lignt', 'Dark', 'DefaultB', 'zhuBeiDong'];
Chinese:
styles = ['青', '明亮', '黑夜', '蓝', '主被动'];
Head/Menu
English:
head = {
center: 'Personal center',
logout: 'Logout',
fullScreen: 'Toggle full screen',
changeStyle: 'Switch themes',
language: 'Language',
zh: 'Chinese',
en: 'English',
size: 'Size',
normal: 'Normal',
small: 'Small',
large: 'Large',
};
Chinese:
head = {
center: '个人中心',
logout: '退出登录',
fullScreen: '切换全屏',
changeStyle: '切换主题',
language: '语言',
zh: '中文',
en: '英文',
size: '尺寸',
normal: '正常',
small: '小',
large: '大',
};
Validation Rules
English:
rule = {
pleaseEnter: 'Please enter ',
notNull: 'There cannot be empty',
pleaseSelect: 'Please select',
formatErr: 'The input format is incorrect',
int: 'Number',
max: 'The max value is {0}',
min: 'The min value is {0}',
maxLen: 'Enter up to {0} character',
minLen: 'Enter a minimum of {0} character',
hexadecimal: 'Please enter hexadecimal digits',
idCard: {
format: 'The ID card is wrong in length or format',
area: 'The ID area is illegal',
birth: 'The date of birth on the ID card is illegal',
error: 'The ID number is illegal',
},
username: [
'The username consists of letters, numbers, and is between 4-16 in length',
"Usernames cannot be underscored '_'",
'Usernames cannot contain spaces',
],
name: 'The name consists of Chinese characters or letters and is no more than 10 in length',
};
HTTP Errors
English:
http = {
unPermission: 'You do not have access yet, please contact your administrator to add it',
noPermission: 'This permission is not yet open, do not access without permission',
error: 'Network error',
downFail: 'Download failed with network abnormality!',
};
Chinese:
http = {
unPermission: '您暂无权访问,请联系管理员添加',
noPermission: '此权限尚未开放,请勿越权访问',
error: '网络错误',
downFail: '下载失败,网络异常!',
unLogin: '请先登录系统',
};
WebSocket Messages
English:
ws = {
status: {
connected: 'Connected',
connecting: 'Connecting...',
disconnected: 'Disconnected',
error: 'Error',
},
autorefresh: {
enabled: 'Autorefresh enabled',
enabling: 'Enabling...',
disabled: 'Autorefresh disabled',
error: 'Autorefresh error',
},
tooltip: {
required: 'Required',
subscribed: 'Subscribed',
error: 'Error',
retry: 'Retry attempt',
clickToToggle: 'Click to enable/disable autorefresh',
retrying: 'Retrying',
errorOccurred: 'An error occurred',
},
};
Chinese:
ws = {
status: {
connected: '已连接',
connecting: '连接中...',
disconnected: '未连接',
error: '错误',
},
autorefresh: {
enabled: '自动刷新已启用',
enabling: '正在启用...',
disabled: '自动刷新已禁用',
error: '自动刷新错误',
},
tooltip: {
required: '需要',
subscribed: '已订阅',
error: '错误',
retry: '重试次数',
clickToToggle: '点击启用/禁用自动刷新',
retrying: '正在重试',
errorOccurred: '发生错误',
},
};
Domain Organization
| Domain | Description |
|---|---|
base |
Common actions (add, delete, save, etc.) |
pwd |
Password and login related |
styles |
Theme style names |
head |
Header/menu labels |
tool |
Tool labels |
rule |
Validation rules |
http |
HTTP error messages |
preMenu |
Predefined menu items |
log |
Log management |
dict |
Dictionary management |
permission |
Permission management |
role |
Role management |
user |
User management |
buffer |
Cache management |
config |
Configuration management |
ws |
WebSocket messages |
Usage Patterns
Direct i18n Usage
import { i18n } from './i18n';
// Simple key
i18n.t('base.add'); // 'Add' or '添加'
// With interpolation
i18n.t('rule.max', { 0: 100 }); // 'The max value is 100'
i18n.t('rule.max', 100); // 'The max value is 100'
Namespace-prefixed Translator
import { createt } from './i18n';
const t = createt('user.'); // Creates translator with 'user.' prefix
t('.title'); // Resolves to 'user.title'
t('.delete'); // Resolves to 'user.delete'
Dynamic Language Registration
import { registerLang } from './i18n';
registerLang('jp', new JapaneseClass());
i18n.locale = 'jp';
Anti-Patterns
- Do not use flat keys for complex hierarchies - Nested objects are fine, but avoid deeply nested structures
- Do not mix languages in one translation class - Each class should contain only one language
- Do not use translation keys as literal strings - Use the dot notation path consistently
- Do not forget to include all translation domains - Missing domains will cause runtime errors
Language: English