tang-ui-x 1.1.0 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1003 -0
- package/components/TActionSheet/index.uvue +15 -2
- package/components/TCollapse/index.uvue +1 -1
- package/components/TCollapse/type.uts +3 -1
- package/components/TCollapseItem/index.uvue +22 -26
- package/components/TDialog/index.uvue +19 -4
- package/components/TEmpty/index.uvue +28 -14
- package/components/TForm/index.uvue +60 -26
- package/components/TForm/type.uts +4 -0
- package/components/TInput/index.uvue +24 -5
- package/components/TInput/type.uts +10 -0
- package/components/TPicker/index.uvue +26 -6
- package/components/TRadioButton/README.md +117 -0
- package/components/TRadioButton/index.uvue +69 -64
- package/components/TSearchBar/index.uvue +19 -4
- package/composables/i18n/error.uts +82 -0
- package/composables/i18n/index.uts +188 -0
- package/composables/i18n/manager-demo.uts +104 -0
- package/composables/i18n/manager.test.uts +182 -0
- package/composables/i18n/manager.uts +336 -0
- package/composables/i18n/register-demo.uts +125 -0
- package/composables/i18n/task22-verification.uts +198 -0
- package/composables/i18n/task23-verification.uts +343 -0
- package/composables/i18n/task8-demo.uts +93 -0
- package/composables/i18n/task8-verification.uts +98 -0
- package/composables/i18n/test-task23.uts +9 -0
- package/composables/i18n/types.uts +46 -0
- package/composables/i18n/useI18n-verification.uts +105 -0
- package/composables/i18n/validation-demo.uts +45 -0
- package/composables/i18n/validation-test.uts +106 -0
- package/composables/useI18n.uts +77 -0
- package/index.uts +23 -0
- package/locales/cross-platform-verification.uts +510 -0
- package/locales/en-US/actionSheet.json +3 -0
- package/locales/en-US/common.json +10 -0
- package/locales/en-US/dialog.json +5 -0
- package/locales/en-US/empty.json +5 -0
- package/locales/en-US/errorState.json +5 -0
- package/locales/en-US/examplePages.json +1236 -0
- package/locales/en-US/examples.json +218 -0
- package/locales/en-US/form.json +11 -0
- package/locales/en-US/input.json +3 -0
- package/locales/en-US/list.json +5 -0
- package/locales/en-US/loading.json +3 -0
- package/locales/en-US/navBar.json +4 -0
- package/locales/en-US/noticeBar.json +3 -0
- package/locales/en-US/picker.json +5 -0
- package/locales/en-US/searchBar.json +4 -0
- package/locales/en-US/textarea.json +3 -0
- package/locales/en-US/toast.json +6 -0
- package/locales/index.uts +79 -0
- package/locales/init-verification.uts +101 -0
- package/locales/loader.uts +251 -0
- package/locales/run-verification.uts +16 -0
- package/locales/zh-CN/actionSheet.json +3 -0
- package/locales/zh-CN/common.json +10 -0
- package/locales/zh-CN/dialog.json +5 -0
- package/locales/zh-CN/empty.json +5 -0
- package/locales/zh-CN/errorState.json +5 -0
- package/locales/zh-CN/examplePages.json +1236 -0
- package/locales/zh-CN/examples.json +218 -0
- package/locales/zh-CN/form.json +11 -0
- package/locales/zh-CN/input.json +3 -0
- package/locales/zh-CN/list.json +5 -0
- package/locales/zh-CN/loading.json +3 -0
- package/locales/zh-CN/navBar.json +4 -0
- package/locales/zh-CN/noticeBar.json +3 -0
- package/locales/zh-CN/picker.json +5 -0
- package/locales/zh-CN/searchBar.json +4 -0
- package/locales/zh-CN/textarea.json +3 -0
- package/locales/zh-CN/toast.json +6 -0
- package/locales/zh-TW/actionSheet.json +3 -0
- package/locales/zh-TW/common.json +8 -0
- package/locales/zh-TW/dialog.json +5 -0
- package/locales/zh-TW/empty.json +5 -0
- package/locales/zh-TW/errorState.json +5 -0
- package/locales/zh-TW/examplePages.json +705 -0
- package/locales/zh-TW/examples.json +218 -0
- package/locales/zh-TW/form.json +11 -0
- package/locales/zh-TW/input.json +3 -0
- package/locales/zh-TW/list.json +5 -0
- package/locales/zh-TW/loading.json +3 -0
- package/locales/zh-TW/navBar.json +4 -0
- package/locales/zh-TW/noticeBar.json +3 -0
- package/locales/zh-TW/picker.json +5 -0
- package/locales/zh-TW/searchBar.json +4 -0
- package/locales/zh-TW/textarea.json +3 -0
- package/locales/zh-TW/toast.json +6 -0
- package/package.json +49 -47
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task 8 功能演示
|
|
3
|
+
* 展示 getAvailableLocales() 和 getCurrentLocale() 的使用
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { I18nManager } from './manager.uts'
|
|
7
|
+
import type { ModularLocaleMessages } from './types.uts'
|
|
8
|
+
|
|
9
|
+
// 获取管理器实例
|
|
10
|
+
const manager = I18nManager.getInstance()
|
|
11
|
+
|
|
12
|
+
// 准备测试数据
|
|
13
|
+
const zhCN: ModularLocaleMessages = {
|
|
14
|
+
common: { confirm: '确定', cancel: '取消' }
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const enUS: ModularLocaleMessages = {
|
|
18
|
+
common: { confirm: 'Confirm', cancel: 'Cancel' }
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const zhTW: ModularLocaleMessages = {
|
|
22
|
+
common: { confirm: '確定', cancel: '取消' }
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// 演示 1: 初始状态
|
|
26
|
+
console.log('=== 演示 1: 初始状态 ===')
|
|
27
|
+
console.log('当前语言:', manager.getCurrentLocale())
|
|
28
|
+
console.log('可用语言:', manager.getAvailableLocales().value)
|
|
29
|
+
console.log('')
|
|
30
|
+
|
|
31
|
+
// 演示 2: 注册语言包
|
|
32
|
+
console.log('=== 演示 2: 注册语言包 ===')
|
|
33
|
+
manager.registerMessages('zh-CN', zhCN)
|
|
34
|
+
console.log('注册 zh-CN 后:')
|
|
35
|
+
console.log(' 可用语言:', manager.getAvailableLocales().value)
|
|
36
|
+
console.log('')
|
|
37
|
+
|
|
38
|
+
manager.registerMessages('en-US', enUS)
|
|
39
|
+
console.log('注册 en-US 后:')
|
|
40
|
+
console.log(' 可用语言:', manager.getAvailableLocales().value)
|
|
41
|
+
console.log('')
|
|
42
|
+
|
|
43
|
+
manager.registerMessages('zh-TW', zhTW)
|
|
44
|
+
console.log('注册 zh-TW 后:')
|
|
45
|
+
console.log(' 可用语言:', manager.getAvailableLocales().value)
|
|
46
|
+
console.log('')
|
|
47
|
+
|
|
48
|
+
// 演示 3: 切换语言
|
|
49
|
+
console.log('=== 演示 3: 切换语言 ===')
|
|
50
|
+
console.log('初始语言:', manager.getCurrentLocale())
|
|
51
|
+
|
|
52
|
+
manager.setLocale('en-US')
|
|
53
|
+
console.log('切换到 en-US:', manager.getCurrentLocale())
|
|
54
|
+
|
|
55
|
+
manager.setLocale('zh-TW')
|
|
56
|
+
console.log('切换到 zh-TW:', manager.getCurrentLocale())
|
|
57
|
+
|
|
58
|
+
manager.setLocale('zh-CN')
|
|
59
|
+
console.log('切换回 zh-CN:', manager.getCurrentLocale())
|
|
60
|
+
console.log('')
|
|
61
|
+
|
|
62
|
+
// 演示 4: 响应式特性
|
|
63
|
+
console.log('=== 演示 4: 响应式特性 ===')
|
|
64
|
+
const availableLocales = manager.getAvailableLocales()
|
|
65
|
+
console.log('获取响应式列表:', availableLocales.value)
|
|
66
|
+
|
|
67
|
+
// 动态注册新语言
|
|
68
|
+
const jaJP: ModularLocaleMessages = {
|
|
69
|
+
common: { confirm: '確認', cancel: 'キャンセル' }
|
|
70
|
+
}
|
|
71
|
+
manager.registerMessages('ja-JP', jaJP)
|
|
72
|
+
console.log('注册 ja-JP 后,列表自动更新:', availableLocales.value)
|
|
73
|
+
console.log('')
|
|
74
|
+
|
|
75
|
+
// 演示 5: 实际应用场景
|
|
76
|
+
console.log('=== 演示 5: 实际应用场景 - 语言选择器 ===')
|
|
77
|
+
console.log('构建语言选择器选项:')
|
|
78
|
+
const locales = manager.getAvailableLocales().value
|
|
79
|
+
const localeNames: Record<string, string> = {
|
|
80
|
+
'zh-CN': '简体中文',
|
|
81
|
+
'en-US': 'English',
|
|
82
|
+
'zh-TW': '繁體中文',
|
|
83
|
+
'ja-JP': '日本語'
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
locales.forEach((locale: string) => {
|
|
87
|
+
const isCurrent = locale === manager.getCurrentLocale()
|
|
88
|
+
const marker = isCurrent ? '✓' : ' '
|
|
89
|
+
console.log(` [${marker}] ${locale} - ${localeNames[locale]}`)
|
|
90
|
+
})
|
|
91
|
+
console.log('')
|
|
92
|
+
|
|
93
|
+
console.log('=== 演示完成 ===')
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task 8 验证脚本
|
|
3
|
+
* 验证 getAvailableLocales() 和 getCurrentLocale() 方法
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { I18nManager } from './manager.uts'
|
|
7
|
+
import type { ModularLocaleMessages } from './types.uts'
|
|
8
|
+
|
|
9
|
+
console.log('=== Task 8 验证:可用语言查询功能 ===\n')
|
|
10
|
+
|
|
11
|
+
// 获取管理器实例
|
|
12
|
+
const manager = I18nManager.getInstance()
|
|
13
|
+
|
|
14
|
+
// 注册测试语言包
|
|
15
|
+
console.log('1. 注册测试语言包...')
|
|
16
|
+
const zhCN: ModularLocaleMessages = {
|
|
17
|
+
common: {
|
|
18
|
+
confirm: '确定',
|
|
19
|
+
cancel: '取消'
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const enUS: ModularLocaleMessages = {
|
|
24
|
+
common: {
|
|
25
|
+
confirm: 'Confirm',
|
|
26
|
+
cancel: 'Cancel'
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const zhTW: ModularLocaleMessages = {
|
|
31
|
+
common: {
|
|
32
|
+
confirm: '確定',
|
|
33
|
+
cancel: '取消'
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
manager.registerMessages('zh-CN', zhCN)
|
|
38
|
+
manager.registerMessages('en-US', enUS)
|
|
39
|
+
manager.registerMessages('zh-TW', zhTW)
|
|
40
|
+
console.log('✓ 已注册 3 个语言包\n')
|
|
41
|
+
|
|
42
|
+
// 测试 getCurrentLocale()
|
|
43
|
+
console.log('2. 测试 getCurrentLocale() 方法')
|
|
44
|
+
const currentLocale = manager.getCurrentLocale()
|
|
45
|
+
console.log(` 当前语言: ${currentLocale}`)
|
|
46
|
+
console.log(` ✓ getCurrentLocale() 返回: ${currentLocale}\n`)
|
|
47
|
+
|
|
48
|
+
// 测试 getAvailableLocales()
|
|
49
|
+
console.log('3. 测试 getAvailableLocales() 方法')
|
|
50
|
+
const availableLocales = manager.getAvailableLocales()
|
|
51
|
+
console.log(` 可用语言列表: ${availableLocales.value.join(', ')}`)
|
|
52
|
+
console.log(` 语言数量: ${availableLocales.value.length}`)
|
|
53
|
+
console.log(` ✓ getAvailableLocales() 返回响应式列表\n`)
|
|
54
|
+
|
|
55
|
+
// 验证列表包含所有注册的语言
|
|
56
|
+
console.log('4. 验证列表与 messages Map 同步')
|
|
57
|
+
const expectedLocales = ['zh-CN', 'en-US', 'zh-TW']
|
|
58
|
+
let allPresent = true
|
|
59
|
+
for (const locale of expectedLocales) {
|
|
60
|
+
const isPresent = availableLocales.value.includes(locale)
|
|
61
|
+
console.log(` ${locale}: ${isPresent ? '✓' : '✗'}`)
|
|
62
|
+
if (!isPresent) allPresent = false
|
|
63
|
+
}
|
|
64
|
+
console.log(` ${allPresent ? '✓' : '✗'} 所有语言都在列表中\n`)
|
|
65
|
+
|
|
66
|
+
// 测试语言切换后 getCurrentLocale() 的更新
|
|
67
|
+
console.log('5. 测试语言切换后 getCurrentLocale() 更新')
|
|
68
|
+
console.log(` 切换前: ${manager.getCurrentLocale()}`)
|
|
69
|
+
manager.setLocale('en-US')
|
|
70
|
+
console.log(` 切换到 en-US`)
|
|
71
|
+
console.log(` 切换后: ${manager.getCurrentLocale()}`)
|
|
72
|
+
console.log(` ✓ getCurrentLocale() 正确反映当前语言\n`)
|
|
73
|
+
|
|
74
|
+
// 测试动态注册后列表更新
|
|
75
|
+
console.log('6. 测试动态注册后列表更新')
|
|
76
|
+
console.log(` 注册前语言数量: ${availableLocales.value.length}`)
|
|
77
|
+
const jaJP: ModularLocaleMessages = {
|
|
78
|
+
common: {
|
|
79
|
+
confirm: '確認',
|
|
80
|
+
cancel: 'キャンセル'
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
manager.registerMessages('ja-JP', jaJP)
|
|
84
|
+
console.log(` 注册 ja-JP 后语言数量: ${availableLocales.value.length}`)
|
|
85
|
+
console.log(` ja-JP 在列表中: ${availableLocales.value.includes('ja-JP') ? '✓' : '✗'}`)
|
|
86
|
+
console.log(` ✓ 列表自动更新\n`)
|
|
87
|
+
|
|
88
|
+
// 验证响应式特性
|
|
89
|
+
console.log('7. 验证 getAvailableLocales() 返回的是 ComputedRef')
|
|
90
|
+
console.log(` 类型检查: ${typeof availableLocales.value}`)
|
|
91
|
+
console.log(` 是数组: ${Array.isArray(availableLocales.value) ? '✓' : '✗'}`)
|
|
92
|
+
console.log(` ✓ 返回响应式 computed 对象\n`)
|
|
93
|
+
|
|
94
|
+
console.log('=== 所有验证通过 ✓ ===')
|
|
95
|
+
console.log('\n需求验证:')
|
|
96
|
+
console.log('✓ 5.1: getAvailableLocales() 返回所有已注册语言的语言代码数组')
|
|
97
|
+
console.log('✓ 5.2: getCurrentLocale() 返回当前激活的语言代码')
|
|
98
|
+
console.log('✓ 5.3: 语言包动态注册后,可用语言列表自动更新并保持准确性')
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* i18n 类型定义
|
|
3
|
+
* 定义多语言系统的所有类型
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 语言包消息类型
|
|
8
|
+
* 每个模块是一个扁平的键值对对象
|
|
9
|
+
*/
|
|
10
|
+
export type LocaleMessages = {
|
|
11
|
+
[key: string]: string | LocaleMessages
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* 模块化语言包类型
|
|
16
|
+
* 按模块名组织
|
|
17
|
+
*/
|
|
18
|
+
export type ModularLocaleMessages = {
|
|
19
|
+
[moduleName: string]: {
|
|
20
|
+
[key: string]: string
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* 语言代码类型
|
|
26
|
+
* 支持内置语言和自定义语言代码
|
|
27
|
+
*/
|
|
28
|
+
export type LocaleCode = 'zh-CN' | 'en-US' | 'zh-TW' | string
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* i18n 配置类型
|
|
32
|
+
*/
|
|
33
|
+
export type I18nConfig = {
|
|
34
|
+
/** 当前语言 */
|
|
35
|
+
locale: LocaleCode
|
|
36
|
+
/** 回退语言 */
|
|
37
|
+
fallbackLocale: LocaleCode
|
|
38
|
+
/** 语言包 */
|
|
39
|
+
messages: Record<string, LocaleMessages>
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* 翻译参数类型
|
|
44
|
+
* 用于字符串插值
|
|
45
|
+
*/
|
|
46
|
+
export type TranslateParams = Record<string, string | number>
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useI18n Composable 验证脚本
|
|
3
|
+
* 验证 useI18n 的基本功能
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { I18nManager } from './manager.uts'
|
|
7
|
+
import { useI18n } from '../useI18n.uts'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* 验证 useI18n Composable
|
|
11
|
+
*/
|
|
12
|
+
export function verifyUseI18n(): void {
|
|
13
|
+
console.log('=== useI18n Composable 验证 ===\n')
|
|
14
|
+
|
|
15
|
+
// 准备测试数据
|
|
16
|
+
const manager = I18nManager.getInstance()
|
|
17
|
+
manager.registerMessages('zh-CN', {
|
|
18
|
+
common: {
|
|
19
|
+
confirm: '确定',
|
|
20
|
+
cancel: '取消',
|
|
21
|
+
hello: '你好,{name}'
|
|
22
|
+
},
|
|
23
|
+
dialog: {
|
|
24
|
+
title: '提示'
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
manager.registerMessages('en-US', {
|
|
29
|
+
common: {
|
|
30
|
+
confirm: 'Confirm',
|
|
31
|
+
cancel: 'Cancel',
|
|
32
|
+
hello: 'Hello, {name}'
|
|
33
|
+
},
|
|
34
|
+
dialog: {
|
|
35
|
+
title: 'Notice'
|
|
36
|
+
}
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
// 测试 useI18n
|
|
40
|
+
const { $t, locale, availableLocales, setLocale } = useI18n()
|
|
41
|
+
|
|
42
|
+
// 1. 测试翻译函数
|
|
43
|
+
console.log('1. 测试翻译函数')
|
|
44
|
+
console.log(' $t("common.confirm"):', $t('common.confirm'))
|
|
45
|
+
console.log(' 预期: "确定"')
|
|
46
|
+
console.log(' 结果:', $t('common.confirm') === '确定' ? '✓ 通过' : '✗ 失败')
|
|
47
|
+
console.log()
|
|
48
|
+
|
|
49
|
+
// 2. 测试带参数的翻译
|
|
50
|
+
console.log('2. 测试带参数的翻译')
|
|
51
|
+
const greeting = $t('common.hello', { name: '张三' })
|
|
52
|
+
console.log(' $t("common.hello", { name: "张三" }):', greeting)
|
|
53
|
+
console.log(' 预期: "你好,张三"')
|
|
54
|
+
console.log(' 结果:', greeting === '你好,张三' ? '✓ 通过' : '✗ 失败')
|
|
55
|
+
console.log()
|
|
56
|
+
|
|
57
|
+
// 3. 测试当前语言(响应式)
|
|
58
|
+
console.log('3. 测试当前语言(响应式)')
|
|
59
|
+
console.log(' locale.value:', locale.value)
|
|
60
|
+
console.log(' 预期: "zh-CN"')
|
|
61
|
+
console.log(' 结果:', locale.value === 'zh-CN' ? '✓ 通过' : '✗ 失败')
|
|
62
|
+
console.log()
|
|
63
|
+
|
|
64
|
+
// 4. 测试可用语言列表
|
|
65
|
+
console.log('4. 测试可用语言列表')
|
|
66
|
+
console.log(' availableLocales.value:', availableLocales.value)
|
|
67
|
+
console.log(' 预期: 包含 "zh-CN" 和 "en-US"')
|
|
68
|
+
const hasZhCN = availableLocales.value.includes('zh-CN')
|
|
69
|
+
const hasEnUS = availableLocales.value.includes('en-US')
|
|
70
|
+
console.log(' 结果:', hasZhCN && hasEnUS ? '✓ 通过' : '✗ 失败')
|
|
71
|
+
console.log()
|
|
72
|
+
|
|
73
|
+
// 5. 测试语言切换
|
|
74
|
+
console.log('5. 测试语言切换')
|
|
75
|
+
const switchResult = setLocale('en-US')
|
|
76
|
+
console.log(' setLocale("en-US"):', switchResult)
|
|
77
|
+
console.log(' 预期: true')
|
|
78
|
+
console.log(' 结果:', switchResult === true ? '✓ 通过' : '✗ 失败')
|
|
79
|
+
console.log()
|
|
80
|
+
|
|
81
|
+
// 6. 验证切换后的翻译
|
|
82
|
+
console.log('6. 验证切换后的翻译')
|
|
83
|
+
console.log(' locale.value:', locale.value)
|
|
84
|
+
console.log(' $t("common.confirm"):', $t('common.confirm'))
|
|
85
|
+
console.log(' 预期语言: "en-US"')
|
|
86
|
+
console.log(' 预期翻译: "Confirm"')
|
|
87
|
+
const localeCorrect = locale.value === 'en-US'
|
|
88
|
+
const translationCorrect = $t('common.confirm') === 'Confirm'
|
|
89
|
+
console.log(' 结果:', localeCorrect && translationCorrect ? '✓ 通过' : '✗ 失败')
|
|
90
|
+
console.log()
|
|
91
|
+
|
|
92
|
+
// 7. 测试无效语言代码
|
|
93
|
+
console.log('7. 测试无效语言代码')
|
|
94
|
+
const invalidResult = setLocale('invalid-locale')
|
|
95
|
+
console.log(' setLocale("invalid-locale"):', invalidResult)
|
|
96
|
+
console.log(' 预期: false')
|
|
97
|
+
console.log(' 当前语言保持不变:', locale.value)
|
|
98
|
+
console.log(' 结果:', invalidResult === false && locale.value === 'en-US' ? '✓ 通过' : '✗ 失败')
|
|
99
|
+
console.log()
|
|
100
|
+
|
|
101
|
+
console.log('=== 验证完成 ===')
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// 如果直接运行此文件,执行验证
|
|
105
|
+
// verifyUseI18n()
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON 结构验证演示
|
|
3
|
+
* 展示 validateMessages 方法的工作原理
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { registerLocale, registerLocaleWithMode, replaceLocale } from './index.uts'
|
|
7
|
+
import type { ModularLocaleMessages } from './types.uts'
|
|
8
|
+
|
|
9
|
+
console.log('=== JSON 结构验证演示 ===\n')
|
|
10
|
+
|
|
11
|
+
// 示例 1: 有效的语言包
|
|
12
|
+
console.log('1. 注册有效的语言包')
|
|
13
|
+
const validMessages: ModularLocaleMessages = {
|
|
14
|
+
common: {
|
|
15
|
+
confirm: '确定',
|
|
16
|
+
cancel: '取消'
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
registerLocale('demo-valid', validMessages)
|
|
20
|
+
console.log('✓ 成功\n')
|
|
21
|
+
|
|
22
|
+
// 示例 2: 无效的语言包(null)
|
|
23
|
+
console.log('2. 尝试注册 null')
|
|
24
|
+
registerLocale('demo-null', null as any)
|
|
25
|
+
console.log('✗ 应该被拒绝\n')
|
|
26
|
+
|
|
27
|
+
// 示例 3: 无效的模块
|
|
28
|
+
console.log('3. 尝试注册无效模块')
|
|
29
|
+
const invalidModule: any = {
|
|
30
|
+
common: 'not an object'
|
|
31
|
+
}
|
|
32
|
+
registerLocale('demo-invalid-module', invalidModule)
|
|
33
|
+
console.log('✗ 应该被拒绝\n')
|
|
34
|
+
|
|
35
|
+
// 示例 4: 无效的键值
|
|
36
|
+
console.log('4. 尝试注册无效键值')
|
|
37
|
+
const invalidValue: any = {
|
|
38
|
+
common: {
|
|
39
|
+
confirm: 123
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
registerLocale('demo-invalid-value', invalidValue)
|
|
43
|
+
console.log('✗ 应该被拒绝\n')
|
|
44
|
+
|
|
45
|
+
console.log('=== 演示完成 ===')
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 验证 JSON 结构验证功能
|
|
3
|
+
* 测试 validateMessages 方法的各种场景
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { I18nManager } from './manager.uts'
|
|
7
|
+
import type { ModularLocaleMessages } from './types.uts'
|
|
8
|
+
|
|
9
|
+
console.log('=== JSON 结构验证测试 ===\n')
|
|
10
|
+
|
|
11
|
+
const manager = I18nManager.getInstance()
|
|
12
|
+
|
|
13
|
+
// 测试 1: 有效的语言包结构
|
|
14
|
+
console.log('测试 1: 有效的语言包结构')
|
|
15
|
+
const validMessages: ModularLocaleMessages = {
|
|
16
|
+
common: {
|
|
17
|
+
confirm: '确定',
|
|
18
|
+
cancel: '取消'
|
|
19
|
+
},
|
|
20
|
+
dialog: {
|
|
21
|
+
title: '提示'
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
manager.registerMessages('test-valid', validMessages)
|
|
25
|
+
console.log('✓ 有效语言包注册成功')
|
|
26
|
+
console.log('可用语言:', manager.getAvailableLocales().value)
|
|
27
|
+
console.log('')
|
|
28
|
+
|
|
29
|
+
// 测试 2: 无效的语言包(null)
|
|
30
|
+
console.log('测试 2: 无效的语言包(null)')
|
|
31
|
+
try {
|
|
32
|
+
manager.registerMessages('test-null', null as any)
|
|
33
|
+
console.log('✗ 应该拒绝 null 语言包')
|
|
34
|
+
} catch (e) {
|
|
35
|
+
console.log('✓ 正确拒绝 null 语言包')
|
|
36
|
+
}
|
|
37
|
+
console.log('')
|
|
38
|
+
|
|
39
|
+
// 测试 3: 无效的语言包(数组)
|
|
40
|
+
console.log('测试 3: 无效的语言包(数组)')
|
|
41
|
+
manager.registerMessages('test-array', [] as any)
|
|
42
|
+
console.log('检查是否注册:', manager.hasLocale('test-array'))
|
|
43
|
+
console.log('')
|
|
44
|
+
|
|
45
|
+
// 测试 4: 无效的模块(不是对象)
|
|
46
|
+
console.log('测试 4: 无效的模块(不是对象)')
|
|
47
|
+
const invalidModule: any = {
|
|
48
|
+
common: 'not an object'
|
|
49
|
+
}
|
|
50
|
+
manager.registerMessages('test-invalid-module', invalidModule)
|
|
51
|
+
console.log('检查是否注册:', manager.hasLocale('test-invalid-module'))
|
|
52
|
+
console.log('')
|
|
53
|
+
|
|
54
|
+
// 测试 5: 无效的键值(不是字符串)
|
|
55
|
+
console.log('测试 5: 无效的键值(不是字符串)')
|
|
56
|
+
const invalidValue: any = {
|
|
57
|
+
common: {
|
|
58
|
+
confirm: 123, // 数字而非字符串
|
|
59
|
+
cancel: '取消'
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
manager.registerMessages('test-invalid-value', invalidValue)
|
|
63
|
+
console.log('检查是否注册:', manager.hasLocale('test-invalid-value'))
|
|
64
|
+
console.log('')
|
|
65
|
+
|
|
66
|
+
// 测试 6: 部分有效的语言包(应该完全拒绝)
|
|
67
|
+
console.log('测试 6: 部分有效的语言包')
|
|
68
|
+
const partiallyValid: any = {
|
|
69
|
+
common: {
|
|
70
|
+
confirm: '确定',
|
|
71
|
+
cancel: '取消'
|
|
72
|
+
},
|
|
73
|
+
dialog: {
|
|
74
|
+
title: '提示',
|
|
75
|
+
invalid: { nested: 'object' } // 嵌套对象而非字符串
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
manager.registerMessages('test-partial', partiallyValid)
|
|
79
|
+
console.log('检查是否注册:', manager.hasLocale('test-partial'))
|
|
80
|
+
console.log('')
|
|
81
|
+
|
|
82
|
+
// 测试 7: 替换模式也应该验证
|
|
83
|
+
console.log('测试 7: 替换模式验证')
|
|
84
|
+
manager.registerMessagesWithMode('test-replace', invalidValue, 'replace')
|
|
85
|
+
console.log('检查是否注册:', manager.hasLocale('test-replace'))
|
|
86
|
+
console.log('')
|
|
87
|
+
|
|
88
|
+
// 测试 8: 空对象是有效的
|
|
89
|
+
console.log('测试 8: 空对象是有效的')
|
|
90
|
+
manager.registerMessages('test-empty', {})
|
|
91
|
+
console.log('✓ 空对象注册成功')
|
|
92
|
+
console.log('检查是否注册:', manager.hasLocale('test-empty'))
|
|
93
|
+
console.log('')
|
|
94
|
+
|
|
95
|
+
// 测试 9: 空模块是有效的
|
|
96
|
+
console.log('测试 9: 空模块是有效的')
|
|
97
|
+
const emptyModule: ModularLocaleMessages = {
|
|
98
|
+
common: {}
|
|
99
|
+
}
|
|
100
|
+
manager.registerMessages('test-empty-module', emptyModule)
|
|
101
|
+
console.log('✓ 空模块注册成功')
|
|
102
|
+
console.log('检查是否注册:', manager.hasLocale('test-empty-module'))
|
|
103
|
+
console.log('')
|
|
104
|
+
|
|
105
|
+
console.log('=== 测试完成 ===')
|
|
106
|
+
console.log('最终可用语言列表:', manager.getAvailableLocales().value)
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useI18n Composable
|
|
3
|
+
* 为组件提供响应式的 i18n 功能
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { computed } from 'vue'
|
|
7
|
+
import type { ComputedRef } from 'vue'
|
|
8
|
+
import { I18nManager } from './i18n/manager.uts'
|
|
9
|
+
import type { TranslateParams } from './i18n/types.uts'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* useI18n 返回类型
|
|
13
|
+
*/
|
|
14
|
+
export interface UseI18nReturn {
|
|
15
|
+
/** 翻译函数 */
|
|
16
|
+
$t: (key: string, params?: TranslateParams) => string
|
|
17
|
+
/** 当前语言(响应式) */
|
|
18
|
+
locale: ComputedRef<string>
|
|
19
|
+
/** 可用语言列表(响应式) */
|
|
20
|
+
availableLocales: ComputedRef<string[]>
|
|
21
|
+
/** 设置语言 */
|
|
22
|
+
setLocale: (locale: string) => boolean
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* useI18n Composable 函数
|
|
27
|
+
* 提供响应式的多语言功能
|
|
28
|
+
*
|
|
29
|
+
* @returns i18n 功能对象
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```typescript
|
|
33
|
+
* const { $t, locale, setLocale, availableLocales } = useI18n()
|
|
34
|
+
*
|
|
35
|
+
* // 翻译文本
|
|
36
|
+
* const title = $t('common.confirm')
|
|
37
|
+
*
|
|
38
|
+
* // 带参数的翻译
|
|
39
|
+
* const greeting = $t('common.hello', { name: '张三' })
|
|
40
|
+
*
|
|
41
|
+
* // 切换语言
|
|
42
|
+
* setLocale('en-US')
|
|
43
|
+
*
|
|
44
|
+
* // 获取当前语言
|
|
45
|
+
* console.log(locale.value)
|
|
46
|
+
*
|
|
47
|
+
* // 获取可用语言列表
|
|
48
|
+
* console.log(availableLocales.value)
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export function useI18n(): UseI18nReturn {
|
|
52
|
+
// 获取 I18nManager 单例实例
|
|
53
|
+
const manager = I18nManager.getInstance()
|
|
54
|
+
|
|
55
|
+
// 翻译函数:调用 manager.translate()
|
|
56
|
+
const $t = (key: string, params?: TranslateParams): string => {
|
|
57
|
+
return manager.translate(key, params)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// 当前语言(响应式 computed)
|
|
61
|
+
const locale = computed<string>(() => manager.currentLocale.value)
|
|
62
|
+
|
|
63
|
+
// 可用语言列表(响应式 computed)
|
|
64
|
+
const availableLocales = manager.getAvailableLocales()
|
|
65
|
+
|
|
66
|
+
// 设置语言方法
|
|
67
|
+
const setLocale = (locale: string): boolean => {
|
|
68
|
+
return manager.setLocale(locale)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return {
|
|
72
|
+
$t,
|
|
73
|
+
locale,
|
|
74
|
+
availableLocales,
|
|
75
|
+
setLocale
|
|
76
|
+
}
|
|
77
|
+
}
|
package/index.uts
CHANGED
|
@@ -30,6 +30,29 @@ export { useTheme } from './composables/useTheme.uts'
|
|
|
30
30
|
export { useToast } from './composables/useToast.uts'
|
|
31
31
|
export { useModal } from './composables/useModal.uts'
|
|
32
32
|
|
|
33
|
+
// 导出 i18n composable
|
|
34
|
+
export { useI18n } from './composables/useI18n.uts'
|
|
35
|
+
export type { UseI18nReturn } from './composables/useI18n.uts'
|
|
36
|
+
|
|
37
|
+
// 导出 i18n 全局函数
|
|
38
|
+
export {
|
|
39
|
+
setLanguage,
|
|
40
|
+
registerLocale,
|
|
41
|
+
registerLocaleWithMode,
|
|
42
|
+
replaceLocale,
|
|
43
|
+
getCurrentLocale,
|
|
44
|
+
getAvailableLocales
|
|
45
|
+
} from './composables/i18n/index.uts'
|
|
46
|
+
|
|
47
|
+
// 导出 i18n 类型定义
|
|
48
|
+
export type {
|
|
49
|
+
LocaleMessages,
|
|
50
|
+
ModularLocaleMessages,
|
|
51
|
+
LocaleCode,
|
|
52
|
+
I18nConfig,
|
|
53
|
+
TranslateParams
|
|
54
|
+
} from './composables/i18n/types.uts'
|
|
55
|
+
|
|
33
56
|
// 版本信息
|
|
34
57
|
export const version: string = '1.0.5'
|
|
35
58
|
|