tang-ui-x 1.1.1 → 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.
Files changed (87) hide show
  1. package/README.md +1003 -0
  2. package/components/TActionSheet/index.uvue +15 -2
  3. package/components/TCollapse/index.uvue +1 -1
  4. package/components/TCollapse/type.uts +3 -1
  5. package/components/TCollapseItem/index.uvue +22 -26
  6. package/components/TDialog/index.uvue +19 -4
  7. package/components/TEmpty/index.uvue +28 -14
  8. package/components/TForm/index.uvue +30 -9
  9. package/components/TForm/type.uts +4 -0
  10. package/components/TInput/index.uvue +24 -5
  11. package/components/TInput/type.uts +10 -0
  12. package/components/TPicker/index.uvue +26 -6
  13. package/components/TSearchBar/index.uvue +19 -4
  14. package/composables/i18n/error.uts +82 -0
  15. package/composables/i18n/index.uts +188 -0
  16. package/composables/i18n/manager-demo.uts +104 -0
  17. package/composables/i18n/manager.test.uts +182 -0
  18. package/composables/i18n/manager.uts +336 -0
  19. package/composables/i18n/register-demo.uts +125 -0
  20. package/composables/i18n/task22-verification.uts +198 -0
  21. package/composables/i18n/task23-verification.uts +343 -0
  22. package/composables/i18n/task8-demo.uts +93 -0
  23. package/composables/i18n/task8-verification.uts +98 -0
  24. package/composables/i18n/test-task23.uts +9 -0
  25. package/composables/i18n/types.uts +46 -0
  26. package/composables/i18n/useI18n-verification.uts +105 -0
  27. package/composables/i18n/validation-demo.uts +45 -0
  28. package/composables/i18n/validation-test.uts +106 -0
  29. package/composables/useI18n.uts +77 -0
  30. package/index.uts +23 -0
  31. package/locales/cross-platform-verification.uts +510 -0
  32. package/locales/en-US/actionSheet.json +3 -0
  33. package/locales/en-US/common.json +10 -0
  34. package/locales/en-US/dialog.json +5 -0
  35. package/locales/en-US/empty.json +5 -0
  36. package/locales/en-US/errorState.json +5 -0
  37. package/locales/en-US/examplePages.json +1236 -0
  38. package/locales/en-US/examples.json +218 -0
  39. package/locales/en-US/form.json +11 -0
  40. package/locales/en-US/input.json +3 -0
  41. package/locales/en-US/list.json +5 -0
  42. package/locales/en-US/loading.json +3 -0
  43. package/locales/en-US/navBar.json +4 -0
  44. package/locales/en-US/noticeBar.json +3 -0
  45. package/locales/en-US/picker.json +5 -0
  46. package/locales/en-US/searchBar.json +4 -0
  47. package/locales/en-US/textarea.json +3 -0
  48. package/locales/en-US/toast.json +6 -0
  49. package/locales/index.uts +79 -0
  50. package/locales/init-verification.uts +101 -0
  51. package/locales/loader.uts +251 -0
  52. package/locales/run-verification.uts +16 -0
  53. package/locales/zh-CN/actionSheet.json +3 -0
  54. package/locales/zh-CN/common.json +10 -0
  55. package/locales/zh-CN/dialog.json +5 -0
  56. package/locales/zh-CN/empty.json +5 -0
  57. package/locales/zh-CN/errorState.json +5 -0
  58. package/locales/zh-CN/examplePages.json +1236 -0
  59. package/locales/zh-CN/examples.json +218 -0
  60. package/locales/zh-CN/form.json +11 -0
  61. package/locales/zh-CN/input.json +3 -0
  62. package/locales/zh-CN/list.json +5 -0
  63. package/locales/zh-CN/loading.json +3 -0
  64. package/locales/zh-CN/navBar.json +4 -0
  65. package/locales/zh-CN/noticeBar.json +3 -0
  66. package/locales/zh-CN/picker.json +5 -0
  67. package/locales/zh-CN/searchBar.json +4 -0
  68. package/locales/zh-CN/textarea.json +3 -0
  69. package/locales/zh-CN/toast.json +6 -0
  70. package/locales/zh-TW/actionSheet.json +3 -0
  71. package/locales/zh-TW/common.json +8 -0
  72. package/locales/zh-TW/dialog.json +5 -0
  73. package/locales/zh-TW/empty.json +5 -0
  74. package/locales/zh-TW/errorState.json +5 -0
  75. package/locales/zh-TW/examplePages.json +705 -0
  76. package/locales/zh-TW/examples.json +218 -0
  77. package/locales/zh-TW/form.json +11 -0
  78. package/locales/zh-TW/input.json +3 -0
  79. package/locales/zh-TW/list.json +5 -0
  80. package/locales/zh-TW/loading.json +3 -0
  81. package/locales/zh-TW/navBar.json +4 -0
  82. package/locales/zh-TW/noticeBar.json +3 -0
  83. package/locales/zh-TW/picker.json +5 -0
  84. package/locales/zh-TW/searchBar.json +4 -0
  85. package/locales/zh-TW/textarea.json +3 -0
  86. package/locales/zh-TW/toast.json +6 -0
  87. package/package.json +2 -1
@@ -0,0 +1,343 @@
1
+ /**
2
+ * Task 23 验证脚本
3
+ * 验证全局函数支持注册模式
4
+ */
5
+
6
+ import {
7
+ registerLocale,
8
+ registerLocaleWithMode,
9
+ replaceLocale,
10
+ setLanguage,
11
+ getCurrentLocale
12
+ } from './index.uts'
13
+ import { I18nManager } from './manager.uts'
14
+
15
+ /**
16
+ * 验证 registerLocale 保持向后兼容(默认合并模式)
17
+ */
18
+ function testRegisterLocaleBackwardCompatibility(): boolean {
19
+ console.log('\n=== 测试 1: registerLocale 向后兼容性(默认合并模式) ===')
20
+
21
+ const manager = I18nManager.getInstance()
22
+
23
+ // 注册初始语言包
24
+ registerLocale('test-locale-1', {
25
+ common: {
26
+ confirm: '确定',
27
+ cancel: '取消',
28
+ ok: '好的'
29
+ },
30
+ dialog: {
31
+ title: '提示',
32
+ confirmText: '确定'
33
+ }
34
+ })
35
+
36
+ // 使用 registerLocale 覆盖部分内容(应该使用合并模式)
37
+ registerLocale('test-locale-1', {
38
+ common: {
39
+ confirm: '好的' // 覆盖这个键
40
+ // cancel 和 ok 应该保留
41
+ }
42
+ })
43
+
44
+ // 验证合并结果
45
+ setLanguage('test-locale-1')
46
+ const messages = manager.messages.get('test-locale-1')
47
+
48
+ if (!messages) {
49
+ console.log('❌ 失败:语言包未注册')
50
+ return false
51
+ }
52
+
53
+ // 检查 common 模块
54
+ const common = messages['common']
55
+ if (!common) {
56
+ console.log('❌ 失败:common 模块不存在')
57
+ return false
58
+ }
59
+
60
+ // 验证覆盖的键
61
+ if (common['confirm'] !== '好的') {
62
+ console.log('❌ 失败:confirm 应该被覆盖为 "好的",实际为:', common['confirm'])
63
+ return false
64
+ }
65
+
66
+ // 验证保留的键
67
+ if (common['cancel'] !== '取消') {
68
+ console.log('❌ 失败:cancel 应该保留为 "取消",实际为:', common['cancel'])
69
+ return false
70
+ }
71
+
72
+ if (common['ok'] !== '好的') {
73
+ console.log('❌ 失败:ok 应该保留为 "好的",实际为:', common['ok'])
74
+ return false
75
+ }
76
+
77
+ // 验证 dialog 模块应该保留
78
+ const dialog = messages['dialog']
79
+ if (!dialog || dialog['title'] !== '提示') {
80
+ console.log('❌ 失败:dialog 模块应该保留')
81
+ return false
82
+ }
83
+
84
+ console.log('✅ 通过:registerLocale 默认使用合并模式')
85
+ return true
86
+ }
87
+
88
+ /**
89
+ * 验证 registerLocaleWithMode 合并模式
90
+ */
91
+ function testRegisterLocaleWithModeMerge(): boolean {
92
+ console.log('\n=== 测试 2: registerLocaleWithMode 合并模式 ===')
93
+
94
+ const manager = I18nManager.getInstance()
95
+
96
+ // 注册初始语言包
97
+ registerLocaleWithMode('test-locale-2', {
98
+ common: {
99
+ confirm: '确定',
100
+ cancel: '取消'
101
+ },
102
+ dialog: {
103
+ title: '提示'
104
+ }
105
+ }, 'merge')
106
+
107
+ // 使用合并模式添加新内容
108
+ registerLocaleWithMode('test-locale-2', {
109
+ common: {
110
+ ok: '好的' // 添加新键
111
+ },
112
+ empty: {
113
+ title: '暂无数据' // 添加新模块
114
+ }
115
+ }, 'merge')
116
+
117
+ const messages = manager.messages.get('test-locale-2')
118
+
119
+ if (!messages) {
120
+ console.log('❌ 失败:语言包未注册')
121
+ return false
122
+ }
123
+
124
+ // 验证原有内容保留
125
+ const common = messages['common']
126
+ if (!common || common['confirm'] !== '确定' || common['cancel'] !== '取消') {
127
+ console.log('❌ 失败:原有 common 内容应该保留')
128
+ return false
129
+ }
130
+
131
+ // 验证新内容添加
132
+ if (common['ok'] !== '好的') {
133
+ console.log('❌ 失败:新键 ok 应该被添加')
134
+ return false
135
+ }
136
+
137
+ // 验证原有模块保留
138
+ const dialog = messages['dialog']
139
+ if (!dialog || dialog['title'] !== '提示') {
140
+ console.log('❌ 失败:原有 dialog 模块应该保留')
141
+ return false
142
+ }
143
+
144
+ // 验证新模块添加
145
+ const empty = messages['empty']
146
+ if (!empty || empty['title'] !== '暂无数据') {
147
+ console.log('❌ 失败:新模块 empty 应该被添加')
148
+ return false
149
+ }
150
+
151
+ console.log('✅ 通过:registerLocaleWithMode 合并模式正常工作')
152
+ return true
153
+ }
154
+
155
+ /**
156
+ * 验证 registerLocaleWithMode 替换模式
157
+ */
158
+ function testRegisterLocaleWithModeReplace(): boolean {
159
+ console.log('\n=== 测试 3: registerLocaleWithMode 替换模式 ===')
160
+
161
+ const manager = I18nManager.getInstance()
162
+
163
+ // 注册初始语言包
164
+ registerLocaleWithMode('test-locale-3', {
165
+ common: {
166
+ confirm: '确定',
167
+ cancel: '取消',
168
+ ok: '好的'
169
+ },
170
+ dialog: {
171
+ title: '提示',
172
+ confirmText: '确定'
173
+ }
174
+ }, 'merge')
175
+
176
+ // 使用替换模式完全替换
177
+ registerLocaleWithMode('test-locale-3', {
178
+ common: {
179
+ confirm: '好的' // 只有这一个键
180
+ }
181
+ // dialog 模块应该被移除
182
+ }, 'replace')
183
+
184
+ const messages = manager.messages.get('test-locale-3')
185
+
186
+ if (!messages) {
187
+ console.log('❌ 失败:语言包未注册')
188
+ return false
189
+ }
190
+
191
+ // 验证只有新内容
192
+ const common = messages['common']
193
+ if (!common) {
194
+ console.log('❌ 失败:common 模块应该存在')
195
+ return false
196
+ }
197
+
198
+ if (common['confirm'] !== '好的') {
199
+ console.log('❌ 失败:confirm 应该是 "好的"')
200
+ return false
201
+ }
202
+
203
+ // 验证原有的其他键被移除
204
+ if ('cancel' in common || 'ok' in common) {
205
+ console.log('❌ 失败:原有的 cancel 和 ok 键应该被移除')
206
+ return false
207
+ }
208
+
209
+ // 验证原有模块被移除
210
+ if ('dialog' in messages) {
211
+ console.log('❌ 失败:原有的 dialog 模块应该被移除')
212
+ return false
213
+ }
214
+
215
+ console.log('✅ 通过:registerLocaleWithMode 替换模式正常工作')
216
+ return true
217
+ }
218
+
219
+ /**
220
+ * 验证 replaceLocale 函数
221
+ */
222
+ function testReplaceLocale(): boolean {
223
+ console.log('\n=== 测试 4: replaceLocale 函数 ===')
224
+
225
+ const manager = I18nManager.getInstance()
226
+
227
+ // 注册初始语言包
228
+ registerLocale('test-locale-4', {
229
+ common: {
230
+ confirm: '确定',
231
+ cancel: '取消',
232
+ ok: '好的'
233
+ },
234
+ dialog: {
235
+ title: '提示'
236
+ },
237
+ empty: {
238
+ title: '暂无数据'
239
+ }
240
+ })
241
+
242
+ // 使用 replaceLocale 完全替换
243
+ replaceLocale('test-locale-4', {
244
+ common: {
245
+ confirm: '好的',
246
+ cancel: '取消'
247
+ }
248
+ // 只保留 common 模块,其他模块应该被移除
249
+ })
250
+
251
+ const messages = manager.messages.get('test-locale-4')
252
+
253
+ if (!messages) {
254
+ console.log('❌ 失败:语言包未注册')
255
+ return false
256
+ }
257
+
258
+ // 验证新内容存在
259
+ const common = messages['common']
260
+ if (!common || common['confirm'] !== '好的' || common['cancel'] !== '取消') {
261
+ console.log('❌ 失败:新的 common 内容应该存在')
262
+ return false
263
+ }
264
+
265
+ // 验证原有的 ok 键被移除
266
+ if ('ok' in common) {
267
+ console.log('❌ 失败:原有的 ok 键应该被移除')
268
+ return false
269
+ }
270
+
271
+ // 验证原有模块被移除
272
+ if ('dialog' in messages || 'empty' in messages) {
273
+ console.log('❌ 失败:原有的 dialog 和 empty 模块应该被移除')
274
+ return false
275
+ }
276
+
277
+ console.log('✅ 通过:replaceLocale 函数正常工作')
278
+ return true
279
+ }
280
+
281
+ /**
282
+ * 验证函数导出
283
+ */
284
+ function testFunctionExports(): boolean {
285
+ console.log('\n=== 测试 5: 函数导出验证 ===')
286
+
287
+ // 验证所有函数都已导出
288
+ if (typeof registerLocale !== 'function') {
289
+ console.log('❌ 失败:registerLocale 未导出')
290
+ return false
291
+ }
292
+
293
+ if (typeof registerLocaleWithMode !== 'function') {
294
+ console.log('❌ 失败:registerLocaleWithMode 未导出')
295
+ return false
296
+ }
297
+
298
+ if (typeof replaceLocale !== 'function') {
299
+ console.log('❌ 失败:replaceLocale 未导出')
300
+ return false
301
+ }
302
+
303
+ console.log('✅ 通过:所有函数都已正确导出')
304
+ return true
305
+ }
306
+
307
+ /**
308
+ * 运行所有测试
309
+ */
310
+ export function runTask23Verification(): void {
311
+ console.log('========================================')
312
+ console.log('Task 23 验证:全局函数支持注册模式')
313
+ console.log('========================================')
314
+
315
+ const results: boolean[] = []
316
+
317
+ results.push(testFunctionExports())
318
+ results.push(testRegisterLocaleBackwardCompatibility())
319
+ results.push(testRegisterLocaleWithModeMerge())
320
+ results.push(testRegisterLocaleWithModeReplace())
321
+ results.push(testReplaceLocale())
322
+
323
+ const passed = results.filter(r => r).length
324
+ const total = results.length
325
+
326
+ console.log('\n========================================')
327
+ console.log(`测试结果: ${passed}/${total} 通过`)
328
+ console.log('========================================')
329
+
330
+ if (passed === total) {
331
+ console.log('✅ Task 23 验证通过!')
332
+ console.log('\n实现的功能:')
333
+ console.log('1. ✅ registerLocale() 保持向后兼容(默认合并模式)')
334
+ console.log('2. ✅ registerLocaleWithMode() 支持指定模式')
335
+ console.log('3. ✅ replaceLocale() 提供便捷的替换方法')
336
+ console.log('4. ✅ 所有函数都已正确导出')
337
+ } else {
338
+ console.log('❌ 部分测试失败,请检查实现')
339
+ }
340
+ }
341
+
342
+ // 如果直接运行此文件,执行验证
343
+ // runTask23Verification()
@@ -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,9 @@
1
+ /**
2
+ * Task 23 简单测试
3
+ * 快速验证新函数是否可用
4
+ */
5
+
6
+ import { runTask23Verification } from './task23-verification.uts'
7
+
8
+ // 运行验证
9
+ runTask23Verification()
@@ -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()