This commit is contained in:
2026-09-24 16:25:22 +08:00
commit 7428184f01
1198 changed files with 314515 additions and 0 deletions
+2
View File
@@ -0,0 +1,2 @@
## 1.0.02025-07-16
本次插件为开放版本,为销售tmui4x向市场贡献的插件,供大家使用,是tmui4x中抽离出来的插件
+46
View File
@@ -0,0 +1,46 @@
// #ifdef APP
import * as i18n from './instans/i18n'
import { I18nOptions,I18nOptionsReally, Tmui4xI18n,Tmui4xI18nTml } from './interface'
export function createI18n(args : I18nOptions | null = null) : Tmui4xI18n {
return new i18n.Tmui4xI18n(args)
}
// #endif
// #ifdef WEB || MP
import * as i18n from './instans/i18n'
import { I18nOptions,I18nOptionsReally,Tmui4xI18n,Tmui4xI18nTml } from './interface'
export * from './interface'
export function createI18n(args : I18nOptions | null = null) : i18n.Tmui4xI18n {
return new i18n.Tmui4xI18n(args)
}
// #endif
let globalI18nInstans : Tmui4xI18n = createI18n();
export const tmxI18n = definePlugin({
install(app : VueApp, config : any | null) {
globalI18nInstans = createI18n(config as I18nOptions | null)
/**
* 组合式代码中使用
*/
app.config.globalProperties.$i18n = () : Tmui4xI18n => globalI18nInstans
// @ts-ignore
app.mixin({
data() {
return {
/**
* 模板vue内及选项式this.i18n可调用使用
*/
i18n: globalI18nInstans as Tmui4xI18n
}
},
onLaunch(){
}
})
}
})
export const $i18n = () : Tmui4xI18n => createI18n()
export const mergeI18nOpts = (args : I18nOptions|null) : I18nOptionsReally => i18n.mergeI18nOpts(args)
+244
View File
@@ -0,0 +1,244 @@
/**
* Vue I18n UTS 使用示例
* 展示如何在UniApp-X中使用移植的vue-i18n库
*/
import { createI18n} from '@/uni_modules/x-vuei18n-s'
import { Tmui4xI18n,NumberFormat,DateTimeFormat} from '@/uni_modules/x-vuei18n-s/interface.uts'
// 示例:创建简单的i18n实例
export function createExampleI18n():Tmui4xI18n{
// 准备消息数据
const messages: UTSJSONObject = {}
// 中文消息
const zhMessages: UTSJSONObject = {
'hello': '你好',
'welcome': '欢迎使用UniApp-X',
'user': {
'name': '用户名',
'age': '年龄',
'profile': '个人资料'
},
'items': {
'apple': '苹果 | 苹果们',
'apple2': '苹果 | 苹果们 | 复杂嵌套{count}',
'book': '书 | 书们'
},
'greeting': '你好,{name}',
'greetingList': '你好,{0}',
'itemCount': '你有 {count} 个项目'
}
// 英文消息
const enMessages: UTSJSONObject = {
'hello': 'Hello',
'welcome': 'Welcome to UniApp-X',
'user': {
'name': 'Username',
'age': 'Age',
'profile': 'Profile'
},
'items': {
'apple': 'apple | apples',
'apple2': 'apple | apples | apples{count}',
'book': 'book | books'
},
'greeting': 'Hello, {name}!',
'greetingList': 'Hello, {0}!',
'itemCount': 'You have {count} items'
}
messages.set('zh-Hans', zhMessages)
messages.set('en', enMessages)
// 创建i18n实例
const i18n = createI18n({locale:'zh-Hans',messages})
return i18n
}
// 示例:基本翻译功能
export function basicTranslationExample() {
const i18n = createExampleI18n()
console.log('=== 基本翻译示例 ===')
// 简单翻译
console.log(i18n.t('hello')) // 输出: 你好
console.log(i18n.t('welcome')) // 输出: 欢迎使用UniApp-X
// 嵌套路径翻译
console.log(i18n.t('user.name')) // 输出: 用户名
console.log(i18n.t('user.profile')) // 输出: 个人资料
// 切换语言
i18n.setLocale('en')
console.log(i18n.t('hello')) // 输出: Hello
console.log(i18n.t('user.name')) // 输出: Username
// 切换回中文
i18n.setLocale('zh-Hans')
}
// 示例:参数插值
export function interpolationExample() {
const i18n = createExampleI18n()
console.log('=== 参数插值示例 ===')
// 命名参数
const namedParams: UTSJSONObject = { 'name': '张三' }
console.log(i18n.t('greeting', namedParams),'----') // 输出: 你好,张三!
// 列表参数
const listParams = ['李四']
console.log(i18n.t('greetingList', listParams)) // 输出: 你好,李四!
// 数字参数
const countParams: UTSJSONObject = { 'count': 5 }
console.log(i18n.t('itemCount', countParams)) // 输出: 你有 5 个项目
}
// 示例:复数处理
export function pluralExample() {
const i18n = createExampleI18n()
console.log('=== 复数处理示例 ===')
// 单数
console.log(i18n.t('items.apple', 0)) // 输出: 苹果
// 复数
console.log(i18n.t('items.apple', 1)) // 输出: 苹果们
console.log(i18n.t('items.apple2', 2,{count:8})) // 输出: 复杂嵌套8
// 切换到英文测试复数
i18n.setLocale('en')
console.log(i18n.t('items.apple', 0)) // 输出: apple
console.log(i18n.t('items.apple', 1)) // 输出: apples
console.log(i18n.t('items.apple2', 2,{count:8})) // 输出: apples8
i18n.setLocale('zh-Hans')
}
// 示例:数字格式化
export function numberFormatExample() {
const i18n = createExampleI18n()
console.log('=== 数字格式化示例 中文 ===')
// 基本数字格式化
console.log(i18n.n(1234)) // 输出: 1,234.56
console.log(i18n.n(1234567.89)) // 输出: 1,234,567.89
// 货币格式化
const currencyOptions:NumberFormat = {
style: 'currency',
currency: 'CNY',
useGrouping:true
}
console.log(i18n.n(1234.56,null, currencyOptions)) // 输出: ¥1,234.56
// 百分比格式化
const percentOptions:NumberFormat = {
style: 'percent'
}
console.log(i18n.n(0.1234,null, percentOptions)) // 输出: 12.34%
console.log('=== 货币式化示例 英文 ===')
// 货币格式化
const currencyOptionsEn:NumberFormat = {
style: 'currency',
currency: 'USD',
useGrouping:true
}
console.log(i18n.n(1234.56,null, currencyOptionsEn))
}
// 示例:日期时间格式化
export function dateTimeFormatExample() {
const i18n = createExampleI18n()
console.log('=== 日期时间格式化示例 ===')
const now = new Date()
// 基本日期格式化
console.log(i18n.d(now)) // 输出: 2024年01月01日 12:00:00
// 自定义格式
const dateOptions:DateTimeFormat = {
year: 'numeric',
month: 'long',
day: 'numeric',
dateSeparator:'',
local:'en'
}
console.log(i18n.d(now,null, dateOptions)) // 输出: 2024年一月1日
// 时间格式
const timeOptions:DateTimeFormat = {
year: '',
month: '',
day: '',
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
}
console.log(i18n.d(now,null, timeOptions)) // 输出: 12:00:00
}
// 示例:检查翻译键是否存在
export function translationExistsExample() {
const i18n = createExampleI18n()
console.log('=== 翻译键存在检查示例 ===')
console.log(i18n.te('hello')) // 输出: true
console.log(i18n.te('user.name')) // 输出: true
console.log(i18n.te('nonexistent.key')) // 输出: false
// 检查特定语言的键
console.log(i18n.te('hello', 'en')) // 输出: true
console.log(i18n.te('hello', 'fr-FR')) // 输出: false
}
// 示例:动态添加翻译
export function dynamicTranslationExample() {
const i18n = createExampleI18n()
console.log('=== 动态翻译示例 ===')
// 添加新的翻译
const newMessages: UTSJSONObject = {
'goodbye': '再见',
'settings': {
'language': '语言设置',
'theme': '主题设置'
}
}
i18n.mergeLocaleMessage('zh-Hans', newMessages)
console.log(i18n.t('goodbye')) // 输出: 再见
console.log(i18n.t('settings.language')) // 输出: 语言设置
console.log('可用语言:', i18n.availableLocales()) // 输出: ['zh-CN', 'en-US']
}
// 运行所有示例
export function runAllExamples() {
console.log('Vue I18n UTS 库示例开始运行...')
// createExampleI18n()
basicTranslationExample()
interpolationExample()
pluralExample()
numberFormatExample()
dateTimeFormatExample()
translationExistsExample()
dynamicTranslationExample()
console.log('Vue I18n UTS 库示例运行完成!')
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,179 @@
{
"tmui4x": {
"cancel": "Cancel",
"confirm": "Confirm",
"success": "Success",
"fail": "Failed",
"warn": "Warning",
"info": "Info",
"clear":"Clear",
"pickerTitle":"Please select",
"calendar":{
"year": "Year",
"month": "Month",
"day": "Day",
"hour": "Hour",
"minute": "Minute",
"second": "Second",
"titleCurrentMonth":"{0} {1}",
"monthCountSelected":"{count} months",
"selectedStatus":"{count} days selected | No date selected | Selected | End date not selected",
"rangStatus":"Start | End | Today",
"tips":"Max {count} days",
"currentMonthTitle":"This month",
"week":"Mon | Tue | Wed | Thu | Fri | Sat | Sun"
},
"betweentTime": {
"start": "Start time",
"end": "End time",
"quiakListTitle":"Today | This week | This month | This year | This quarter",
"quiakListTitle2":"Last {count} days",
"quiakListTitle3":"Previous {count} years",
"title":"Please select time",
"splite":"to"
},
"uploadFile":{
"title":"Select file",
"uploadStatus":"Pending upload | Uploading... | Upload failed | Upload successful | Exceeds size",
"tips1":"Deletion prohibited during upload",
"tips2":"Deletion prohibited for uploaded files"
},
"pickerSelected":{
"placeholder":"Please enter keywords",
"search":"Search",
"selected":"{count} items selected",
"claer":"Clear selection",
"selectedMode":"Currently in single selection mode",
"selectedALl":"Select all"
},
"tree":{
"changeTitle":"Modify content",
"addTitle":"Add subordinate",
"inputTitle":"Title",
"inputId":"Identifier ID",
"inputTips1":"Do not repeat, auto-generate when empty"
},
"input":{
"placeholder":"Please select or fill in"
},
"inputTag":{
"placeholder": "Please enter and press Enter",
"tips": "Cannot be empty",
"tips2": "Exceeds maximum limit: {count}",
"btnText": "Add Tag"
},
"keyboard":{
"placeholder":"Safe keyboard for secure input",
"space":"Space",
"confirm":"Confirm"
},
"pickerTime":{
"hour":"Hour",
"minute":"Minute",
"second":"Second"
},
"cascader":{
"placeholder":"Please select",
"currentPlaceholder":"Select current"
},
"pickerDate":{
"placeholder":"Please select time",
"year":"Year",
"month":"Month",
"day":"Day",
"hour":"Hour",
"minute":"Minute",
"second":"Second"
},
"uploadMedia":{
"tips1":"Dragging sort not allowed during upload",
"videoPreview":"Video preview",
"close":"Close",
"systemError":"System error",
"limitMaxCount":"Exceeded max upload count",
"uploadStatus":"Pending upload | Uploading... | Upload failed | Upload successful | Exceeds size"
},
"checkbox":{
"tips":"Exceeds maximum selection"
},
"weekbar":{
"week":"Mon | Tue | Wed | Thu | Fri | Sat | Sun"
},
"pagination":{
"prev": "Previous",
"next": "Next"
},
"search":{
"placeholder":"Enter keywords",
"cancel":"Cancel"
},
"xmore":{
"off": "Expand more",
"on": "Collapse more"
},
"empty":{
"moreLabel": "No more data",
"errorLabel": "Error~",
"btnLabel": "Retry",
"title":"No data"
},
"xloading":{
"label":"Loading..."
},
"actionModal":{
"title":"Reminder",
"btnText":"Confirm"
},
"actionMenu":{
"title":"Please select",
"btnText":"Confirm"
},
"pullRefresh":{
"status_1":"Refreshing",
"status_2":"Pull down more",
"status_3":"Release to refresh",
"status_4":"Refresh done",
"status_5":"Refresh failed"
},
"virtualList":{
"status_0":"Pull down more",
"status_1":"Release to refresh",
"status_2":"Refreshing",
"status_3":"Cancel refresh",
"status_4":"Refresh timeout, retry",
"status_5":"Refresh done"
},
"imageResize":{
"ok":"Done",
"cancel":"Cancel",
"reset":"Reset"
},
"colorView":{
"rgb":"RGB",
"hub":"Spectrum",
"grid":"Palette",
"alpha":"Alpha",
"hex":"HEX",
"r":"Red",
"g":"Green",
"b":"Blue"
},
"modal": {
"title": "Title"
},
"mention": {
"placeholder": "Enter content, @select friend, press confirm"
},
"slideVerify": {
"tipsText": "Drag to position",
"tipsTextSuccess": "Verified",
"tipsTextFail": "Verification failed"
},
"xRequest":{
"error":"Server error:",
"success":"Success",
"hostFailEmpty":"Domain empty",
"loading":"Loading"
}
}
}
@@ -0,0 +1,179 @@
{
"tmui4x": {
"cancel": "キャンセル",
"confirm": "確認",
"success": "成功",
"fail": "失敗",
"warn": "警告",
"info": "情報",
"clear":"クリア",
"pickerTitle":"選択してください",
"calendar":{
"year": "年",
"month": "月",
"day": "日",
"hour": "時",
"minute": "分",
"second": "秒",
"titleCurrentMonth":"{0}年{1}月",
"monthCountSelected":"{count}ヶ月",
"selectedStatus":"選択済み{count}日 | 日付未選択 | 選択済み | 終了日未選択",
"rangStatus":"開始 | 終了 | 本日",
"tips":"最大選択{count}日",
"currentMonthTitle":"今月",
"week":"月曜日 | 火曜日 | 水曜日 | 木曜日 | 金曜日 | 土曜日 | 日曜日"
},
"betweentTime": {
"start": "開始時間",
"end": "終了時間",
"quiakListTitle":"本日 | 今週 | 今月 | 今年 | 今四半期",
"quiakListTitle2":"最近{count}日",
"quiakListTitle3":"前{count}年",
"title":"時間を選択してください",
"splite":"から"
},
"uploadFile":{
"title":"ファイルを選択",
"uploadStatus":"アップロード待機 | アップロード中... | アップロード失敗 | アップロード成功 | サイズ超過",
"tips1":"アップロード中は削除禁止",
"tips2":"アップロード済みファイルは削除禁止"
},
"pickerSelected":{
"placeholder":"キーワードを入力してください",
"search":"検索",
"selected":"選択済み{count}項目",
"claer":"選択をクリア",
"selectedMode":"現在は単一選択モード",
"selectedALl":"すべて選択"
},
"tree":{
"changeTitle":"内容を変更",
"addTitle":"下位を追加",
"inputTitle":"タイトル",
"inputId":"識別ID",
"inputTips1":"重複しないでください、空の場合は自動生成"
},
"input":{
"placeholder":"選択または入力してください"
},
"inputTag":{
"placeholder":"入力してEnterを押してください",
"tips":"空にできません",
"tips2":"制限最大数を超過:{count}",
"btnText":"タグを追加"
},
"keyboard":{
"placeholder":"安全キーボードで安心入力",
"space":"スペース",
"confirm":"確認"
},
"pickerTime":{
"hour":"時間",
"minute":"分",
"second":"秒数"
},
"cascader":{
"placeholder":"選択してください",
"currentPlaceholder":"本級を選択"
},
"pickerDate":{
"placeholder":"時間を選択してください",
"year":"年",
"month":"月",
"day":"日",
"hour":"時",
"minute":"分",
"second":"秒"
},
"uploadMedia":{
"tips1":"アップロード中はドラッグソート禁止",
"videoPreview":"ビデオプレビュー",
"close":"閉じる",
"systemError":"システム異常",
"limitMaxCount":"最大アップロード数を超過",
"uploadStatus":"アップロード待機 | アップロード中... | アップロード失敗 | アップロード成功 | サイズ超過"
},
"checkbox":{
"tips":"最大選択数を超過"
},
"weekbar":{
"week":"月曜日 | 火曜日 | 水曜日 | 木曜日 | 金曜日 | 土曜日 | 日曜日"
},
"pagination":{
"prev": "前のページ",
"next": "次のページ"
},
"search":{
"placeholder":"キーワードを入力",
"cancel":"キャンセル"
},
"xmore":{
"off": "もっと展開",
"on": "もっと収納"
},
"empty":{
"moreLabel": "データなし",
"errorLabel": "エラー",
"btnLabel": "リトライ",
"title":"データなし"
},
"xloading":{
"label":"ロード中..."
},
"actionModal":{
"title":"リマインダー",
"btnText":"確認"
},
"actionMenu":{
"title":"選択してください",
"btnText":"確認"
},
"pullRefresh":{
"status_1":"リフレッシュ中",
"status_2":"さらに下に引っ張る",
"status_3":"離してリフレッシュ",
"status_4":"リフレッシュ完了",
"status_5":"リフレッシュ失敗"
},
"virtualList":{
"status_0":"さらに下に引っ張る",
"status_1":"離してリフレッシュ",
"status_2":"リフレッシュ中",
"status_3":"リフレッシュキャンセル",
"status_4":"リフレッシュタイムアウト、リトライ",
"status_5":"リフレッシュ完了"
},
"imageResize":{
"ok":"完了",
"cancel":"キャンセル",
"reset":"リセット"
},
"colorView":{
"rgb":"RGB",
"hub":"スペクトル",
"grid":"カラーパレット",
"alpha":"透明度",
"hex":"HEX",
"r":"赤",
"g":"緑",
"b":"青"
},
"modal": {
"title": "タイトル"
},
"mention": {
"placeholder": "内容を入力、@で友達選択、確認押す"
},
"slideVerify": {
"tipsText": "指定位置にドラッグ",
"tipsTextSuccess": "検証成功",
"tipsTextFail": "検証失敗"
},
"xRequest":{
"error":"サーバーエラー:",
"success":"操作成功",
"hostFailEmpty":"リクエストドメイン未入力",
"loading":"ロード中"
}
}
}
@@ -0,0 +1,179 @@
{
"tmui4x": {
"cancel": "취소",
"confirm": "확인",
"success": "성공",
"fail": "실패",
"warn": "경고",
"info": "정보",
"clear":"지우기",
"pickerTitle":"선택하세요",
"calendar":{
"year": "년",
"month": "월",
"day": "일",
"hour": "시",
"minute": "분",
"second": "초",
"titleCurrentMonth":"{0}년{1}월",
"monthCountSelected":"{count}개월",
"selectedStatus":"선택됨{count}일 | 날짜 미선택 | 선택됨 | 종료일 미선택",
"rangStatus":"시작 | 종료 | 오늘",
"tips":"최대선택{count}일",
"currentMonthTitle":"이번 달",
"week":"월요일 | 화요일 | 수요일 | 목요일 | 금요일 | 토요일 | 일요일"
},
"betweentTime": {
"start": "시작 시간",
"end": "종료 시간",
"quiakListTitle":"오늘 | 이번 주 | 이번 달 | 올해 | 이번 분기",
"quiakListTitle2":"최근 {count}일",
"quiakListTitle3":"이전 {count}년",
"title":"시간을 선택하세요",
"splite":"부터"
},
"uploadFile":{
"title":"파일 선택",
"uploadStatus":"업로드 대기 | 업로드 중... | 업로드 실패 | 업로드 성공 | 크기 초과",
"tips1":"업로드 중 삭제 금지",
"tips2":"업로드된 파일 삭제 금지"
},
"pickerSelected":{
"placeholder":"키워드를 입력하세요",
"search":"검색",
"selected":"선택됨{count}개",
"claer":"선택 지우기",
"selectedMode":"현재 단일 선택 모드",
"selectedALl":"모두 선택"
},
"tree":{
"changeTitle":"내용 수정",
"addTitle":"하위 추가",
"inputTitle":"제목",
"inputId":"식별 ID",
"inputTips1":"중복하지 마세요, 비어있으면 자동 생성"
},
"input":{
"placeholder":"선택하거나 입력하세요"
},
"inputTag":{
"placeholder":"입력 후 엔터를 누르세요",
"tips":"비워둘 수 없습니다",
"tips2":"최대 수 초과:{count}",
"btnText":"태그 추가"
},
"keyboard":{
"placeholder":"안전한 키보드로 안심 입력",
"space":"스페이스",
"confirm":"확인"
},
"pickerTime":{
"hour":"시간",
"minute":"분",
"second":"초수"
},
"cascader":{
"placeholder":"선택하세요",
"currentPlaceholder":"본급 선택"
},
"pickerDate":{
"placeholder":"시간을 선택하세요",
"year":"년",
"month":"월",
"day":"일",
"hour":"시",
"minute":"분",
"second":"초"
},
"uploadMedia":{
"tips1":"업로드 중 드래그 정렬 금지",
"videoPreview":"비디오 미리보기",
"close":"닫기",
"systemError":"시스템 이상",
"limitMaxCount":"최대 업로드 수 초과",
"uploadStatus":"업로드 대기 | 업로드 중... | 업로드 실패 | 업로드 성공 | 크기 초과"
},
"checkbox":{
"tips":"최대 선택 수 초과"
},
"weekbar":{
"week":"월요일 | 화요일 | 수요일 | 목요일 | 금요일 | 토요일 | 일요일"
},
"pagination":{
"prev": "이전 페이지",
"next": "다음 페이지"
},
"search":{
"placeholder":"키워드 입력",
"cancel":"취소"
},
"xmore":{
"off": "더 펼치기",
"on": "더 접기"
},
"empty":{
"moreLabel": "데이터 없음",
"errorLabel": "오류",
"btnLabel": "재시도",
"title":"데이터 없음"
},
"xloading":{
"label":"로드 중..."
},
"actionModal":{
"title":"리마인더",
"btnText":"확인"
},
"actionMenu":{
"title":"선택하세요",
"btnText":"확인"
},
"pullRefresh":{
"status_1":"새로고침 중",
"status_2":"더 아래로 끌기",
"status_3":"놓아서 새로고침",
"status_4":"새로고침 완료",
"status_5":"새로고침 실패"
},
"virtualList":{
"status_0":"더 아래로 끌기",
"status_1":"놓아서 새로고침",
"status_2":"새로고침 중",
"status_3":"새로고침 취소",
"status_4":"새로고침 타임아웃, 재시도",
"status_5":"새로고침 완료"
},
"imageResize":{
"ok":"완료",
"cancel":"취소",
"reset":"리셋"
},
"colorView":{
"rgb":"RGB",
"hub":"스펙트럼",
"grid":"팔레트",
"alpha":"투명도",
"hex":"HEX",
"r":"빨강",
"g":"녹색",
"b":"파랑"
},
"modal": {
"title": "제목"
},
"mention": {
"placeholder": "내용 입력, @로 친구 선택, 확인 누르기"
},
"slideVerify": {
"tipsText": "지정 위치로 드래그",
"tipsTextSuccess": "검증 성공",
"tipsTextFail": "검증 실패"
},
"xRequest":{
"error":"서버 오류:",
"success":"작업 성공",
"hostFailEmpty":"요청 도메인 미입력",
"loading":"로드 중"
}
}
}
@@ -0,0 +1,181 @@
{
"tmui4x": {
"cancel": "取消",
"confirm": "确认",
"success": "成功",
"fail": "失败",
"warn": "警告",
"info": "提醒",
"clear":"清空",
"pickerTitle":"请选择",
"calendar":{
"year": "年",
"month": "月",
"day": "日",
"hour": "时",
"minute": "分",
"second": "秒",
"titleCurrentMonth":"{0}年{1}月",
"monthCountSelected":"{count}月",
"selectedStatus":"已选择{count}日 | 未选择日期 | 已选择 | 未选择结束日期",
"rangStatus":"开始 | 结束 | 本日",
"tips":"最大选择{count}日",
"currentMonthTitle":"本月",
"week":"周一 | 周二 | 周三 | 周四 | 周五 | 周六 | 周日"
},
"betweentTime": {
"start": "开始时间",
"end": "结束时间",
"quiakListTitle":"本日 | 本周 | 本月 | 本年 | 本季度",
"quiakListTitle2":"最近{count}天",
"quiakListTitle3":"前{count}年",
"title":"请选择时间",
"splite":"至"
},
"uploadFile":{
"title":"选择文件",
"uploadStatus":"待上传 | 上传中... | 上传失败 | 上传成功 | 超过大小",
"tips1":"上传中禁止删除",
"tips2":"已上传文件禁止删除"
},
"pickerSelected":{
"placeholder":"请输入关键词",
"search":"搜索",
"selected":"已选择{count}项",
"claer":"清空选择",
"selectedMode":"当前为单选模式",
"selectedALl":"选择所有"
},
"tree":{
"changeTitle":"修改内容",
"addTitle":"添加下级",
"inputTitle":"标题",
"inputId":"标识ID",
"inputTips1":"不要重复,空时自动生成"
},
"input":{
"placeholder":"请选择或者填写"
},
"inputTag":{
"placeholder":"请输入并回车",
"tips":"不能为空",
"tips2":"超过限制最大数:{count}",
"btnText":"添加标签"
},
"keyboard":{
"placeholder":"安全键盘放心输入",
"space":"空格",
"confirm":"确认"
},
"pickerTime":{
"hour":"小时",
"minute":"分钟",
"second":"秒数"
},
"cascader":{
"placeholder":"请选择",
"currentPlaceholder":"选择本级"
},
"pickerDate":{
"placeholder":"请选择时间",
"year":"年",
"month":"月",
"day":"日",
"hour":"时",
"minute":"分",
"second":"秒"
},
"uploadMedia":{
"tips1":"上传中不允许拖动排序",
"videoPreview":"视频预览",
"close":"关闭",
"systemError":"系统异常",
"limitMaxCount":"已超最大上传数量",
"uploadStatus":"待上传 | 上传中... | 上传失败 | 上传成功 | 超过大小"
},
"checkbox":{
"tips":"超过最大选择"
},
"weekbar":{
"week": "周一 | 周二 | 周三 | 周四 | 周五 | 周六 | 周日"
},
"pagination":{
"prev": "上一页",
"next": "下一页"
},
"search":{
"placeholder":"请输入关键词",
"cancel":"取消"
},
"xmore":{
"off": "展开更多",
"on": "收起更多"
},
"empty":{
"moreLabel": "没有更多数据啦",
"errorLabel": "出错啦~",
"btnLabel": "点击重试",
"title":"当前没有数据"
},
"xloading":{
"label":"加载中..."
},
"actionModal":{
"title":"提醒",
"btnText":"确认"
},
"actionMenu":{
"title":"请选择",
"btnText":"确认"
},
"pullRefresh":{
"status_1":"正在刷新",
"status_2":"继续下拉",
"status_3":"松开刷新",
"status_4":"刷新完成",
"status_5":"刷新失败"
},
"virtualList":{
"status_0":"继续下拉",
"status_1":"松开刷新",
"status_2":"刷新中",
"status_3":"取消刷新",
"status_4":"刷新超时,点击重试",
"status_5":"刷新完成"
},
"imageResize":{
"ok":"完成",
"cancel":"取消",
"reset":"还原"
},
"colorView":{
"rgb":"RGB",
"hub":"光谱",
"grid":"色卡",
"alpha":"透明度",
"hex":"HEX",
"r":"红色",
"g":"绿色",
"b":"蓝色"
},
"modal": {
"title": "标题"
},
"mention": {
"placeholder": "请输入内容,@选择朋友,按确认完成"
},
"slideVerify": {
"tipsText": "请拖动到指定位置",
"tipsTextSuccess": "验证成功",
"tipsTextFail": "验证失败"
},
"xRequest":{
"error":"服务器错误:",
"success":"操作成功",
"hostFailEmpty":"未填请求域名",
"loading":"加载中"
}
}
}
@@ -0,0 +1,179 @@
{
"tmui4x": {
"cancel": "取消",
"confirm": "確認",
"success": "成功",
"fail": "失敗",
"warn": "警告",
"info": "提醒",
"clear":"清空",
"pickerTitle":"請選擇",
"calendar":{
"year": "年",
"month": "月",
"day": "日",
"hour": "時",
"minute": "分",
"second": "秒",
"titleCurrentMonth":"{0}年{1}月",
"monthCountSelected":"{count}月",
"selectedStatus":"已選擇{count}日 | 未選擇日期 | 已選擇 | 未選擇結束日期",
"rangStatus":"開始 | 結束 | 本日",
"tips":"最大選擇{count}日",
"currentMonthTitle":"本月",
"week":"週一 | 週二 | 週三 | 週四 | 週五 | 週六 | 週日"
},
"betweentTime": {
"start": "開始時間",
"end": "結束時間",
"quiakListTitle":"本日 | 本週 | 本月 | 本年 | 本季度",
"quiakListTitle2":"最近{count}天",
"quiakListTitle3":"前{count}年",
"title":"請選擇時間",
"splite":"至"
},
"uploadFile":{
"title":"選擇檔案",
"uploadStatus":"待上傳 | 上傳中... | 上傳失敗 | 上傳成功 | 超過大小",
"tips1":"上傳中禁止刪除",
"tips2":"已上傳檔案禁止刪除"
},
"pickerSelected":{
"placeholder":"請輸入關鍵詞",
"search":"搜尋",
"selected":"已選擇{count}項",
"claer":"清空選擇",
"selectedMode":"當前為單選模式",
"selectedALl":"選擇所有"
},
"tree":{
"changeTitle":"修改內容",
"addTitle":"添加下級",
"inputTitle":"標題",
"inputId":"標識ID",
"inputTips1":"不要重複,空時自動生成"
},
"input":{
"placeholder":"請選擇或者填寫"
},
"inputTag":{
"placeholder":"請輸入並回車",
"tips":"不能為空",
"tips2":"超過限制最大數:{count}",
"btnText":"添加標籤"
},
"keyboard":{
"placeholder":"安全鍵盤放心輸入",
"space":"空格",
"confirm":"確認"
},
"pickerTime":{
"hour":"小時",
"minute":"分鐘",
"second":"秒數"
},
"cascader":{
"placeholder":"請選擇",
"currentPlaceholder":"選擇本級"
},
"pickerDate":{
"placeholder":"請選擇時間",
"year":"年",
"month":"月",
"day":"日",
"hour":"時",
"minute":"分",
"second":"秒"
},
"uploadMedia":{
"tips1":"上傳中不允许拖動排序",
"videoPreview":"視頻預覽",
"close":"關閉",
"systemError":"系統異常",
"limitMaxCount":"已超最大上傳數量",
"uploadStatus":"待上傳 | 上傳中... | 上傳失敗 | 上傳成功 | 超過大小"
},
"checkbox":{
"tips":"超過最大選擇"
},
"weekbar":{
"week":"週一 | 週二 | 週三 | 週四 | 週五 | 週六 | 週日"
},
"pagination":{
"prev": "上一頁",
"next": "下一頁"
},
"search":{
"placeholder":"請輸入關鍵詞",
"cancel":"取消"
},
"xmore":{
"off": "展開更多",
"on": "收起更多"
},
"empty":{
"moreLabel": "沒有更多數據啦",
"errorLabel": "出錯啦~",
"btnLabel": "點擊重試",
"title":"當前沒有數據"
},
"xloading":{
"label":"加載中..."
},
"actionModal":{
"title":"提醒",
"btnText":"確認"
},
"actionMenu":{
"title":"請選擇",
"btnText":"確認"
},
"pullRefresh":{
"status_1":"正在刷新",
"status_2":"繼續下拉",
"status_3":"鬆開刷新",
"status_4":"刷新完成",
"status_5":"刷新失敗"
},
"virtualList":{
"status_0":"繼續下拉",
"status_1":"鬆開刷新",
"status_2":"刷新中",
"status_3":"取消刷新",
"status_4":"刷新超時,點擊重試",
"status_5":"刷新完成"
},
"imageResize":{
"ok":"完成",
"cancel":"取消",
"reset":"還原"
},
"colorView":{
"rgb":"RGB",
"hub":"光譜",
"grid":"色卡",
"alpha":"透明度",
"hex":"HEX",
"r": "紅色",
"g": "綠色",
"b": "藍色"
},
"modal": {
"title": "標題"
},
"mention": {
"placeholder": "請輸入內容,@選擇朋友,按確認完成"
},
"slideVerify": {
"tipsText": "請拖動到指定位置",
"tipsTextSuccess": "驗證成功",
"tipsTextFail": "驗證失敗"
},
"xRequest":{
"error":"服務器錯誤:",
"success":"操作成功",
"hostFailEmpty":"未填請求域名",
"loading":"加載中"
}
}
}
+417
View File
@@ -0,0 +1,417 @@
// 统一类型定义 - 替换联合类型
export type StringOrNull = string | null
export type NumberOrNull = number | null
export type StringOrNumber = string | number
export type StringOrNumberOrNull = string | number | null
export type DateOrNumberOrString = Date | number | string
export type UTSJSONObjectOrNull = UTSJSONObject | null
export type UTSJSONObjectOrArray = UTSJSONObject | Array<any>
export type AnyOrNull = any | null
export type StringOrMessageFunction = string | MessageFunction
export type StringOrVoid = string | void
export type GetAnyType = (obj : AnyOrNull) => AnyOrNull
export type I18nOptionsOrNull = I18nOptions | null
export type NumberFormatOrNull = NumberFormat | null
export type DateTimeFormatOrNull = DateTimeFormat | null
export type GetAnyTypeOrNull = GetAnyType | null
/**
* 警告处理器类型 - 用于处理国际化过程中的警告信息
* @param msg 警告消息内容
* @param err 可选的错误对象
*/
export type WarnHandler = (msg : StringOrNumberOrNull, err ?: Error) => void
/**
* 基础复数规则函数类型 - 定义基本的复数形式选择逻辑
* @param choice 数量值
* @param choicesLength 可选择的复数形式数量
* @returns 选择的复数形式索引
*/
export type BasePluralRule = (choice : number, choicesLength : number) => number
/**
* 复数规则类型 - 扩展的复数规则,支持回退到原始规则
* @param choice 数量值
* @param choicesLength 可选择的复数形式数量
* @param orgRule 可选的原始复数规则
* @returns 选择的复数形式索引
*/
export type PluralRule = (choice : number, choicesLength : number, orgRule ?: BasePluralRule) => number
/**
* 消息上下文类型 - 包含消息处理所需的所有上下文信息
*/
export type MessageContext = {
/** 列表参数 */
list : Array<any>
/** 命名参数对象 */
named : UTSJSONObject
/** 复数索引 */
pluralIndex : number
/** 复数规则函数 */
pluralRule ?: PluralRule
/** 原始复数规则函数 */
orgPluralRule ?: BasePluralRule
/** 字符串修饰器函数 */
modifier : (str : string) => string
/** 消息内容或消息函数 */
message : StringOrMessageFunction
/** 消息类型 */
type : string
/** 插值函数 */
interpolate : (val : any) => string
/** 值标准化函数 */
normalize : (values : Array<any>) => Array<any>
/** 参数值数组 */
values : Array<any>
}
/**
* 消息函数类型 - 接收上下文并返回格式化后的字符串
* @param ctx 消息上下文
* @returns 格式化后的消息字符串
*/
export type MessageFunction = (ctx : MessageContext) => string
/**
* 消息函数返回值类型
*/
export type MessageFunctionReturn = StringOrNumber
/**
* 数字格式化选项类型 - 基于 ECMA-402 Intl.NumberFormat 标准
*/
export type NumberFormat = {
/** 数字样式:'decimal'(十进制)、'currency'(货币)、'percent'(百分比) */
style ?: string
/** 货币代码,如 'USD'、'EUR'、'CNY' */
currency ?: string
/** 本地化代码 */
local ?: string
/** 货币显示方式:'symbol'(符号)、'code'(代码)、'name'(名称) */
currencyDisplay ?: string
/** 是否使用千分位分组 */
useGrouping ?: boolean
/** 最小整数位数 */
minimumIntegerDigits ?: number
/** 最小小数位数 */
minimumFractionDigits ?: number
/** 最大小数位数 */
maximumFractionDigits ?: number
/** 最小有效数字位数 */
minimumSignificantDigits ?: number
/** 最大有效数字位数 */
maximumSignificantDigits ?: number
}
/**
* 数字格式化选项类型(必填版本)- 所有字段都是必需的
*/
export type NumberFormatOpts = {
/** 数字样式 */
style : string
/** 本地化代码 */
local : string
/** 货币代码 */
currency : string
/** 货币显示方式 */
currencyDisplay : string
/** 是否使用千分位分组 */
useGrouping : boolean
/** 最小整数位数 */
minimumIntegerDigits : number
/** 最小小数位数 */
minimumFractionDigits : number | null
/** 最大小数位数 */
maximumFractionDigits : number | null
/** 最小有效数字位数 */
minimumSignificantDigits : number | null
/** 最大有效数字位数 */
maximumSignificantDigits : number | null
}
/**
* 数字格式化配置映射 - 语言代码 -> 格式名称 -> 格式配置
*/
export type NumberFormats = Map<string, Map<string, NumberFormat>>
/**
* 日期时间格式化选项类型 - 基于 ECMA-402 Intl.DateTimeFormat 标准
*/
export type DateTimeFormat = {
/** 本地化匹配算法:'lookup' 或 'best fit' */
localeMatcher ?: string
/** 本地化代码 */
local ?: string
/** 日历系统,如 'gregory'、'chinese'、'islamic'、'buddhist'、'coptic'、'dangi'、'ethioaa'、'ethiopic'、'hebrew'、'indian'、'iso8601'、'japanese'、'persian'、'roc' */
calendar ?: string
/** 数字系统,如 'arab'、'arabext'、'bali'、'beng'、'deva'、'fullwide'、'gujr'、'guru'、'hanidec'、'khmr'、'knda'、'laoo'、'latn'、'limb'、'mlym'、'mong'、'mymr'、'orya'、'tamldec'、'telu'、'thai'、'tibt' */
numberingSystem ?: string
/** 时区标识符,如 'UTC'、'Asia/Shanghai'、'America/New_York' */
timeZone ?: string
/** 是否使用12小时制 */
hour12 ?: boolean
/** 小时周期:'h11'(0-11 with AM/PM)、'h12'(1-12 with AM/PM)、'h23'(0-23)、'h24'(1-24) */
hourCycle ?: string
/** 格式匹配算法:'basic' 或 'best fit' */
formatMatcher ?: string
/** 日期分隔符:用于连接年月日的字符,如 '-'、'/'、'.' 等。设置后将输出纯数字格式(如 2025-5-3),忽略语言默认的文字后缀 */
dateSeparator ?: string
/** 星期显示:'long'(Monday)、'short'(Mon)、'narrow'(M) */
weekday ?: string
/** 纪元显示:'long'(Anno Domini)、'short'(AD)、'narrow'(A) */
era ?: string
/** 年份显示:'numeric'(2023)、'2-digit'(23) */
year ?: string
/** 月份显示:'numeric'(1)、'2-digit'(01)、'long'(January)、'short'(Jan)、'narrow'(J) */
month ?: string
/** 日期显示:'numeric'(1)、'2-digit'(01) */
day ?: string
/** 时段显示:'long'(in the morning)、'short'(AM)、'narrow'(a) */
dayPeriod ?: string
/** 小时显示:'numeric'(1)、'2-digit'(01) */
hour ?: string
/** 分钟显示:'numeric'(1)、'2-digit'(01) */
minute ?: string
/** 秒显示:'numeric'(1)、'2-digit'(01) */
second ?: string
/** 小数秒位数:0-3,控制毫秒显示精度 */
fractionalSecondDigits ?: number
/** 时区名称显示:'long'(Pacific Standard Time)、'short'(PST)、'shortOffset'(GMT-8)、'longOffset'(GMT-08:00)、'shortGeneric'(PT)、'longGeneric'(Pacific Time) */
timeZoneName ?: string
/** 日期样式:'full'、'long'、'medium'、'short' - 与单独的日期组件选项互斥 */
dateStyle ?: string
/** 时间样式:'full'、'long'、'medium'、'short' - 与单独的时间组件选项互斥 */
timeStyle ?: string
}
export type DateTimeFormatReal = {
/** 本地化匹配算法:'lookup' 或 'best fit' */
localeMatcher : string
/** 本地化代码 */
local : string
/** 日历系统,如 'gregory'、'chinese'、'islamic'、'buddhist'、'coptic'、'dangi'、'ethioaa'、'ethiopic'、'hebrew'、'indian'、'iso8601'、'japanese'、'persian'、'roc' */
calendar : string
/** 数字系统,如 'arab'、'arabext'、'bali'、'beng'、'deva'、'fullwide'、'gujr'、'guru'、'hanidec'、'khmr'、'knda'、'laoo'、'latn'、'limb'、'mlym'、'mong'、'mymr'、'orya'、'tamldec'、'telu'、'thai'、'tibt' */
numberingSystem : string
/** 时区标识符,如 'UTC'、'Asia/Shanghai'、'America/New_York' */
timeZone : string
/** 是否使用12小时制 */
hour12 : boolean
/** 小时周期:'h11'(0-11 with AM/PM)、'h12'(1-12 with AM/PM)、'h23'(0-23)、'h24'(1-24) */
hourCycle : string
/** 格式匹配算法:'basic' 或 'best fit' */
formatMatcher : string
/** 日期分隔符:用于连接年月日的字符,如 '-'、'/'、'.' 等。设置后将输出纯数字格式(如 2025-5-3),忽略语言默认的文字后缀 */
dateSeparator : string
/** 星期显示:'long'(Monday)、'short'(Mon)、'narrow'(M) */
weekday : string
/** 纪元显示:'long'(Anno Domini)、'short'(AD)、'narrow'(A) */
era : string
/** 年份显示:'numeric'(2023)、'2-digit'(23) */
year : string
/** 月份显示:'numeric'(1)、'2-digit'(01)、'long'(January)、'short'(Jan)、'narrow'(J) */
month : string
/** 日期显示:'numeric'(1)、'2-digit'(01) */
day : string
/** 时段显示:'long'(in the morning)、'short'(AM)、'narrow'(a) */
dayPeriod : string
/** 小时显示:'numeric'(1)、'2-digit'(01) */
hour : string
/** 分钟显示:'numeric'(1)、'2-digit'(01) */
minute : string
/** 秒显示:'numeric'(1)、'2-digit'(01) */
second : string
/** 小数秒位数:0-3,控制毫秒显示精度 */
fractionalSecondDigits : number
/** 时区名称显示:'long'(Pacific Standard Time)、'short'(PST)、'shortOffset'(GMT-8)、'longOffset'(GMT-08:00)、'shortGeneric'(PT)、'longGeneric'(Pacific Time) */
timeZoneName : string
/** 日期样式:'full'、'long'、'medium'、'short' - 与单独的日期组件选项互斥 */
dateStyle : string
/** 时间样式:'full'、'long'、'medium'、'short' - 与单独的时间组件选项互斥 */
timeStyle : string
}
/**
* 日期时间格式化配置映射 - 语言代码 -> 格式名称 -> 格式配置
*/
export type DateTimeFormats = Map<string, Map<string, DateTimeFormat>>
/**
* I18n配置选项类型(可选版本)- 用于初始化国际化实例
*/
export type I18nOptions = {
/** 当前语言代码,如 'en-US'、'zh-CN' */
locale ?: string
/** 回退语言代码,当当前语言缺少翻译时使用 */
fallbackLocale ?: string
/** 翻译消息对象,按语言代码组织 */
messages ?: UTSJSONObject
/** 日期时间格式化配置 */
datetimeFormats ?: DateTimeFormats
/** 数字格式化配置 */
numberFormats ?: NumberFormats
/** 字符串修饰器映射 */
modifiers ?: Map<string, MessageFunction>
/** 复数规则映射,按语言代码组织 */
pluralRules ?: Map<string, PluralRule>
/** 缺失翻译处理函数 */
missing ?: ((locale : string, key : string, instance ?: any, type ?: string) => StringOrVoid) | null
/** 是否显示缺失翻译警告 */
missingWarn ?: boolean
/** 是否显示回退语言警告 */
fallbackWarn ?: boolean
/** 是否回退到根实例 */
fallbackRoot ?: boolean
/** 是否启用回退格式化 */
fallbackFormat ?: boolean
/** 是否允许未解析的翻译键 */
unresolving ?: boolean
/** 翻译后处理函数 */
postTranslation ?: ((str : string, key : string) => string) | null
/** 是否警告HTML消息 */
warnHtmlMessage ?: boolean
/** 是否转义参数 */
escapeParameter ?: boolean
/** 是否继承父级语言设置 */
inheritLocale ?: boolean
/** 警告处理器 */
warnHandler ?: WarnHandler
/** 默认复数规则 */
pluralRule ?: PluralRule
/** 是否全局注入 */
globalInjection ?: boolean
/** 是否允许组合式API */
allowComposition ?: boolean
/** 是否使用遗留模式 */
legacy ?: boolean
}
/**
* I18n配置选项类型(必填版本)- 内部使用的完整配置对象
* 参考语言代码标准:https://xnxy.github.io/2024/06/11/%E5%9B%BD%E9%99%85%E5%8C%96%E4%B8%AD%E5%B8%B8%E7%94%A8BCP-47%20Code%E5%92%8C%E8%AF%AD%E8%A8%80%E5%AF%B9%E7%85%A7%E8%A1%A8/
*/
export type I18nOptionsReally = {
/** 当前语言代码,如 'en-US'、'zh-CN' */
locale : string
/** 回退语言代码,当当前语言缺少翻译时使用 */
fallbackLocale : string
/** 翻译消息对象,按语言代码组织 */
messages : UTSJSONObject
/** 日期时间格式化配置 */
datetimeFormats : DateTimeFormats
/** 数字格式化配置 */
numberFormats : NumberFormats
/** 字符串修饰器映射 */
modifiers : Map<string, MessageFunction>
/** 复数规则映射,按语言代码组织 */
pluralRules : Map<string, PluralRule>
/** 缺失翻译处理函数 */
missing : ((locale : string, key : string, instance ?: any, type ?: string) => StringOrVoid) | null
/** 是否显示缺失翻译警告 */
missingWarn : boolean
/** 是否显示回退语言警告 */
fallbackWarn : boolean
/** 是否回退到根实例 */
fallbackRoot : boolean
/** 是否启用回退格式化 */
fallbackFormat : boolean
/** 是否允许未解析的翻译键 */
unresolving : boolean
/** 翻译后处理函数 */
postTranslation : ((str : string, key : string) => string) | null
/** 是否警告HTML消息 */
warnHtmlMessage : boolean
/** 是否转义参数 */
escapeParameter : boolean
/** 是否继承父级语言设置 */
inheritLocale : boolean
/** 警告处理器 */
warnHandler : WarnHandler
/** 默认复数规则 */
pluralRule : PluralRule
/** 是否全局注入 */
globalInjection : boolean
/** 是否允许组合式API */
allowComposition : boolean
/** 是否使用遗留模式 */
legacy : boolean
}
/**
* uniapp-x下的tmui4x附带的多语言插件,现面向所有用户开放本语言插件。
* @author tmui4x
* @copyright https://tmui.design
* @date 2025/7/8
*/
export interface Tmui4xI18nTml {
/** 实例配置,可以动态修改本配置 **/
ops : I18nOptionsReally
/** 设置语言 */
setLocale(local : string) : void;
/**
* 获取语言
* @returns {string} 当前设置的语言
*/
getLocale() : string;
/**
* 获取回退语言
* @returns {string} 当前回退的语言
*/
getFallbackLocale() : string;
/** 设置回退语言 */
setFallbackLocale(local : string) :void;
/** 全量填充配置 **/
setOptions(args : I18nOptions|null):void;
/**
* 翻译方法 - 参考 Vue I18n 实现(UTS类型安全优化版本)
* @param key 翻译键
* @param args 可选参数:数字(用于复数)、对象(用于插值)、字符串(locale)等同原vueI18n使用方式
* @param opts 可选的第二个参数当args为复数数字,key中函数 | 时,此opts起效且必须为utsjsonobject格式等同原vueI18n使用方式
* @returns 翻译后的字符串
*/
t(key : string, ...argsopts : Array<any>) : string;
/**
* 数字格式化方法 - 参考 Vue I18n 实现
* @param val 要格式化的数字
* @param name 格式化名称模板,如果不存在以opts为准,如果opts也没有则取默认值。
* @param opts 格式化选项
* @returns 格式化后的字符串
*/
n(val : number, formatName ?: string, opts ?: NumberFormat) : string;
/**
* 日期时间格式化方法 - 参考 Vue I18n 实现
* @param val 要格式化的日期时间值(Date对象、时间戳数字或日期字符串)
* @param formatName 格式化名称模板,如果不存在以opts为准,如果opts也没有则取默认值
* @param opts 格式化选项
* @returns 格式化后的字符串
*/
d(val : DateOrNumberOrString, formatName ?: string, opts ?: DateTimeFormat) : string;
/**
* 动态添加语言的新字段
* @param {string} local 语言
* @param {UTSJSONObject} newMessage 键值及字段。
*/
mergeLocaleMessage (local : string, newMessage : UTSJSONObject) : void;
/**
* 检测翻译键是否存在 - 参考 Vue I18n 的 te 方法实现
* @param {string} key 翻译键,支持嵌套路径如 'user.name'
* @param {string} locale 可选的语言代码,不提供则使用当前语言
* @returns {boolean} 存在返回true,不存在返回false
*/
te(key : string, locale ?: string) : boolean;
/**
* 相对时间
* @param {stringnumberDate} timeValue 时间差(毫秒)
* @param {string} unit 首选单位,它会自动进阶更高的维度,比如提供秒,超过60秒以分为单位进阶。
* @param {string} locale 可选语言,不提供以默认创建的设置为准。
* @returns {string} 格式化后的时间字符串
*/
rt(timeValues ?: number | Date | string, units ?: string, locale ?: string) : string;
/**
* 获取可用语言列表
* @returns {string[]}
*/
availableLocales() : string[]
}
/**
* 导出Tmui4xI18n国际化核心类
*/
export { Tmui4xI18n } from './instans/i18n'
+97
View File
@@ -0,0 +1,97 @@
{
"id": "x-vuei18n-s",
"displayName": "uts Uvue i18n 多语言插件",
"version": "1.0.0",
"description": "本插件为单文件版本的uts多语言插件具体见readme",
"keywords": [
"tmui4x,uts,i18n,多语言"
],
"repository": "",
"engines": {
"HBuilderX": "^3.6.8",
"uni-app": "",
"uni-app-x": "^4.71"
},
"dcloudext": {
"type": "uts",
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "",
"darkmode": "√",
"i18n": "√",
"widescreen": "√"
},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "√",
"aliyun": "√",
"alipay": "√"
},
"client": {
"uni-app": {
"vue": {
"vue2": "-",
"vue3": "-"
},
"web": {
"safari": "-",
"chrome": "-"
},
"app": {
"vue": "-",
"nvue": "-",
"android": "-",
"ios": "-",
"harmony": "-"
},
"mp": {
"weixin": "-",
"alipay": "-",
"toutiao": "-",
"baidu": "-",
"kuaishou": "-",
"jd": "-",
"harmony": "-",
"qq": "-",
"lark": "-"
},
"quickapp": {
"huawei": "-",
"union": "-"
}
},
"uni-app-x": {
"web": {
"safari": "√",
"chrome": "√"
},
"app": {
"android": "√",
"ios": "√",
"harmony": "√"
},
"mp": {
"weixin": "√"
}
}
}
}
}
}
+397
View File
@@ -0,0 +1,397 @@
# x-vuei18n-s
一个为 UniApp-X 设计的国际化(i18n)插件,提供完整的多语言支持功能。
本库为tmui4x提供多语言支持,同时也是开源免费的,不需要tmui4x授权,您即可导入和下载使用
使用时请按照文档安装和使用。
使用方式几乎与源Vu8I18n一致基本没有变化,所以你看我下面的文档和看官方的文档都可以,但部分函数还是有差异的
[源官方文档链接](https://vue-i18n.intlify.dev/guide/essentials/started.html)
## 特性
- 🌍 多语言翻译支持
- 🔢 复数形式处理
- 📅 日期时间格式化
- 💰 数字格式化
- ⏰ 相对时间格式化
- 🎯 插值和参数替换
- 🔄 语言回退机制
- 📱 跨平台兼容
| Harmony | IOS | Android | WEB | 小程序 |
| --- | --- | --- | --- | --- |
| 支持 | 支持 | 支持 | 支持 | 支持 |
## 安装
将插件复制到项目的 `uni_modules` 目录下即可。
地区语言代码标准见[打开链接](https://xnxy.github.io/2024/06/11/%E5%9B%BD%E9%99%85%E5%8C%96%E4%B8%AD%E5%B8%B8%E7%94%A8BCP-47%20Code%E5%92%8C%E8%AF%AD%E8%A8%80%E5%AF%B9%E7%85%A7%E8%A1%A8/)
## 在TMUI4x项目中使用
### 前置条件
你已经使用并安装tmui4x组件库,那么会自带集成,但需要你复制本插件到您的项目中,目录
```您的项目 > uni_modules > x-vuei18n-s```
接着安装语言包
```uts
import App from './App'
import {xui} from "@/uni_modules/tmx-ui/index.uts"
import {Tmui4xOptions} from "@/uni_modules/tmx-ui/interface.uts"
import en from "@/uni_modules/tmx-ui/localLanuage/en.json"
import zhHans from "@/uni_modules/tmx-ui/localLanuage/zh-Hans.json"
import zhHant from "@/uni_modules/tmx-ui/localLanuage/zh-Hant.json"
import ko from "@/uni_modules/tmx-ui/localLanuage/ko.json"
import ja from "@/uni_modules/tmx-ui/localLanuage/ja.json"
// 下方是组件的语言包,以及你自己定义的语言包与组件合并即可。共用一个实例。
const messages : UTSJSONObject = {
"en":{
...en,
"hellow":"Hi~"
},
"zh-Hans":{
...zhHans,
"hellow":"哈喽"
},
"zh-Hant":zhHant,
"ko":ko,
"ja":ja
}
import { createSSRApp } from 'vue'
export function createApp() {
const app = createSSRApp(App)
// 配置语言包
app.use(xui,{i18nOptions:{locale:"zh-Hans",messages}} as Tmui4xOptions)
return {
app
}
}
```
### 在Uvue内使用
#### 组合式模板内
```uts
import {xStore} from "@/uni_modules/tmx-ui/index.uts"
const i18n = xStore.xConfig.i18n
console.log(i18n.t('xx.x'))
```
uts内导入后可以在模板内使用
```vue
<x-text>{{i18n.t('xx.x')}}</x-text>
```
#### 选项式模板内
它已经集成了,不需要向组合式那样再导入.
```uts
export default {
methods:{
test():string{
return this!.i18n.t('xx.x')
}
}
}
```
它已经集成了,不需要向组合式那样再导入.
```vue
<x-text>{{i18n!.t('xx.x')}}</x-text>
```
### 在任意Uts中使用
```uts
import {xStore} from "@/uni_modules/tmx-ui/index.uts"
const i18n = xStore.xConfig.i18n
console.log(i18n.t('xx.x'))
```
## 作为插件集成到您应用中(非tmui4x项目)
### 前置条件
你需要在main.uts中安装插件
```uts
import { tmxI18n} from "@/uni_modules/x-vuei18n-s/index.uts"
import { I18nOptions} from "@/uni_modules/x-vuei18n-s/interface.uts"
const config = {locale:'zh'} as I18nOptions
app.use(tmxI18n,config)
```
**在下面的2和3取得的i18n均为多语言实例,你可以调用前面的实例方法动态添加语言或者切语言等**
### 1.在Vue模板内使用
```vue
<x-text>{{i18n.t('cnacel')}}</x-text>
```
### 2.在组合式代码内使用
```ts
import {getCurrentInstance} from "vue"
const i18n = getCurrentInstance()?.proxy?.$i18n()
//可选
console.log(i18n?.t('confirm'))
//断言
console.log(i18n!.t('confirm'))
```
### 3.在选项式代码内使用
```ts
export default {
methods:{
test():string{
return this!.i18n.t('confirm')
}
}
}
```
### 4.在任意文件中使用
这里说的是你脱离了vue模板,比如在非setup和选项式中使用时,前面的方式就不行了,因为前面是依赖于vue实例。
此种方式是只使用插件模式不需要在main.uts中app.use安装本插件,即可在任意位置导入使用。包括在vue模板内(不分组合式和选项都能用)
如果你想在模板内使用本方式
**不要再使用i18n变量名了**
因为本身在模板内就有全局的i18n。
任意uts代码中
```uts
import { $i18n } from "@/uni_modules/x-vuei18n-s/index.uts"
const la = $i18n()
// uts文件中就可以使用了。
console.log(la.t('xx.x.x.'))
//模板内
```
vue模板内
```uts
import { $i18n } from "@/uni_modules/x-vuei18n-s/index.uts"
const la = $i18n()
```
```vue
<x-text>{{la.t('xx.x.x.')}}</x-text>
```
## 快速开始
### 基本使用
```typescript
import { $i18n} from "@/uni_modules/x-vuei18n-s/index.uts"
const i18n = $i18n();
```
```typescript
// 设置中文消息
const zhMessages: UTSJSONObject = {
'hello': '你好',
'welcome': '欢迎使用UniApp-X',
'user': {
'name': '用户名',
'age': '年龄'
},
'items': {
'apple': '苹果 | 苹果们 | {count}个苹果'
},
'greeting': '你好,{name}'
}
// 设置英文消息
const enMessages: UTSJSONObject = {
'hello': 'Hello',
'welcome': 'Welcome to UniApp-X',
'user': {
'name': 'Username',
'age': 'Age'
},
'items': {
'apple': 'apple | apples | {count} of apple'
},
'greeting': 'Hello, {name}!'
}
i18n.mergeLocaleMessage('zh',zhMessages)
i18n.mergeLocaleMessage('en',enMessages)
// 设置当前语言
i18n.setLocale('zh')
```
## API 文档
### 创建实例
如果是在uvue模板内,可以参照文档尾部的使用方法。
```typescript
import { $i18n} from "@/uni_modules/x-vuei18n-s/index.uts"
const i18n = $i18n();
```
### 翻译方法 t()
基本翻译:
```typescript
i18n.t('hello') // '你好'
i18n.t('user.name') // '用户名'
```
带参数的翻译:
```typescript
i18n.t('greeting', { name: '张三' }) // '你好,张三!'
```
复数形式:
```typescript
i18n.t('items.apple', 1) // '苹果'
i18n.t('items.apple', 2) // '苹果们'
i18n.t('items.apple', 5, { count: 5 }) // '5个苹果'
```
### 数字格式化 n()
```typescript
// 基本数字格式化
i18n.n(1234.56) // '1234.56'
// 货币格式化
i18n.n(1234.56, null, {
style: 'currency',
currency: 'CNY'
}) // '¥1,234.56'
// 百分比格式化
i18n.n(0.85, null, {
style: 'percent'
}) // '85%'
```
### 日期时间格式化 d()
```typescript
const date = new Date()
// 基本日期格式化
i18n.d(date) // '2024/1/15'
// 自定义格式
i18n.d(date, null, {
year: 'numeric',
month: 'long',
day: 'numeric'
}) // '2024年1月15日'
// 时间格式化
i18n.d(date, null, {
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
}) // '14:30:25'
```
### 相对时间格式化 rt()
```typescript
// 相对于当前时间
i18n.rt(new Date()) // '刚刚'
// 指定时间字符串
i18n.rt('2025-7-8 20:4:50', 'second') // '6个月后'
// 时间戳
i18n.rt(Date.now() + 3600000, 'minute') // '1小时后'
// 自动单位进阶
i18n.rt(Date.now() + 90000, 'second') // '1分钟后' (90秒自动转为分钟)
```
### 翻译键存在性检测 te()
```typescript
// 检测翻译键是否存在
i18n.te('hello') // true
i18n.te('user.name') // true
i18n.te('nonexistent.key') // false
// 检测指定语言中的翻译键
i18n.te('hello', 'zh') // true
i18n.te('hello', 'en') // true
i18n.te('hello', 'fr') // false (如果没有法语语言包)
// 检测嵌套键
i18n.te('user.settings.theme') // true
i18n.te('user.nonexistent') // false
```
### 语言管理
```typescript
// 获取当前语言
const currentLocale = i18n.getLocale() // 'zh'
// 设置语言
i18n.setLocale('en')
// 获取可用语言列表
const locales = i18n.availableLocales() // ['zh', 'en']
// 动态添加语言内容
i18n.mergeLocaleMessage('zh', {
'newKey': '新内容'
})
```
## 高级功能
### 复数规则自定义
```typescript
// pluralRule
const i18n.ops = (choice: number, choicesLength: number) => {
// 自定义复数规则
if (choicesLength === 2) {
return choice === 1 ? 1 : 0
}
return choice === 0 ? 0 : choice === 1 ? 1 : 2
}
}
```
### 回退语言设置
```typescript
i18n.setLocale('zh')
i18n.setFallbackLocale('en')
```
### 预定义格式
```typescript
// 数字格式预定义
i18n.ops.numberFormats.set('zh', new Map([
['currency', {
style: 'currency',
currency: 'CNY',
currencyDisplay: 'symbol'
}]
]))
// 使用预定义格式
i18n.n(1234.56, 'currency') // '¥1,234.56'
```
## 注意事项
1. 消息对象必须使用 `UTSJSONObject` 类型
2. 复数形式使用 `|` 分隔不同的形式
3. 插值参数使用 `{key}` 格式
4. 相对时间会自动选择最合适的单位
5. 支持嵌套的消息键(如 `user.name`
## 许可证
请不要随意更改源码,你仅有使用权。
@@ -0,0 +1,3 @@
{
"minSdkVersion": "20"
}
@@ -0,0 +1,195 @@
<template>
<view>
</view>
</template>
<script lang="uts">
/**
* 引用 Android 系统库
* [可选实现,按需引入]
*/
import TextUtils from 'android.text.TextUtils';
import Button from 'android.widget.Button';
import View from 'android.view.View';
/**
* 引入三方库
* [可选实现,按需引入]
*
* 在 Android 平台引入三方库有以下两种方式:
* 1、[推荐] 通过 仓储 方式引入,将 三方库的依赖信息 配置到 config.json 文件下的 dependencies 字段下。详细配置方式[详见](https://uniapp.dcloud.net.cn/plugin/uts-plugin.html#dependencies)
* 2、直接引入,将 三方库的aar或jar文件 放到libs目录下。更多信息[详见](https://uniapp.dcloud.net.cn/plugin/uts-plugin.html#android%E5%B9%B3%E5%8F%B0%E5%8E%9F%E7%94%9F%E9%85%8D%E7%BD%AE)
*
* 在通过上述任意方式依赖三方库后,使用时需要在文件中 import
* import { LottieAnimationView } from 'com.airbnb.lottie.LottieAnimationView'
*/
/**
* UTSAndroid 为平台内置对象,不需要 import 可直接调用其API[详见](https://uniapp.dcloud.net.cn/uts/utsandroid.html#utsandroid)
*/
//原生提供以下属性或方法的实现
export default {
/**
* 组件名称,也就是开发者使用的标签
*/
name: "uts-button",
/**
* 组件涉及的事件声明,只有声明过的事件,才能被正常发送
*/
emits: ['buttonclick'],
/**
* 属性声明,组件的使用者会传递这些属性值到组件
*/
props: {
"buttontext": {
type: String,
default: "点击触发"
}
},
/**
* 组件内部变量声明
*/
data() {
return {}
},
/**
* 属性变化监听器实现
*/
watch: {
"buttontext": {
/**
* 这里监听属性变化,并进行组件内部更新
*/
handler(newValue : string, oldValue : string) {
if (!TextUtils.isEmpty(newValue) && newValue != oldValue) {
this.$el?.setText(newValue);
}
},
immediate: false // 创建时是否通过此方法更新属性,默认值为false
},
},
/**
* 规则:如果没有配置expose,则methods中的方法均对外暴露,如果配置了expose,则以expose的配置为准向外暴露
* ['publicMethod'] 含义为:只有 `publicMethod` 在实例上可用
*/
expose: ['doSomething'],
methods: {
/**
* 对外公开的组件方法
*
* uni-app中调用示例:
* this.$refs["组件ref"].doSomething("uts-button");
*
* uni-app x中调用示例:
* 1、引入对应Element
* import { UtsButtonElement(组件名称以upper camel case方式命名 + Element) } from 'uts.sdk.modules.utsComponent(组件目录名称以lower camel case方式命名)';
* 2、(this.$refs["组件ref"] as UtsButtonElement).doSomething("uts-button");
* 或 (uni.getElementById("组件id") as UtsButtonElement).doSomething("uts-button");
*/
doSomething(param : string) {
console.log(param);
},
/**
* 内部使用的组件方法
*/
privateMethod() {
}
},
/**
* [可选实现] 组件被创建,组件第一个生命周期,
* 在内存中被占用的时候被调用,开发者可以在这里执行一些需要提前执行的初始化逻辑
*/
created() {
},
/**
* [可选实现] 对应平台的view载体即将被创建,对应前端beforeMount
*/
NVBeforeLoad() {
},
/**
* [必须实现] 创建原生View,必须定义返回值类型
* 开发者需要重点实现这个函数,声明原生组件被创建出来的过程,以及最终生成的原生组件类型
* Android需要明确知道View类型,需特殊校验)
*/
NVLoad() : Button {
let button = new Button($androidContext!);
button.setText("点击触发");
button.setOnClickListener(new ButtonClickListener(this));
return button;
},
/**
* [可选实现] 原生View已创建
*/
NVLoaded() {
},
/**
* [可选实现] 原生View布局完成
*/
NVLayouted() {
},
/**
* [可选实现] 原生View将释放
*/
NVBeforeUnload() {
},
/**
* [可选实现] 原生View已释放,这里可以做释放View之后的操作
*/
NVUnloaded() {
},
/**
* [可选实现] 组件销毁
*/
unmounted() {
},
/**
* [可选实现] 自定组件布局尺寸,用于告诉排版系统,组件自身需要的宽高
* 一般情况下,组件的宽高应该是由终端系统的排版引擎决定,组件开发者不需要实现此函数
* 但是部分场景下,组件开发者需要自己维护宽高,则需要开发者重写此函数
*/
NVMeasure(size : UTSSize) : UTSSize {
// size.width = 300.0.toFloat();
// size.height = 200.0.toFloat();
return size;
}
}
/**
* 定义按钮点击后触发回调的类
* [可选实现]
*/
class ButtonClickListener extends View.OnClickListener {
/**
* 如果需要在回调类或者代理类中对组件进行操作,比如调用组件方法,发送事件等,需要在该类中持有组件对应的原生类的对象
* 组件原生类的基类为 UTSComponent,该类是一个泛型类,需要接收一个类型变量,该类型变量就是原生组件的类型
*/
private comp : UTSComponent<Button>;
constructor(comp : UTSComponent<Button>) {
super();
this.comp = comp;
}
/**
* 按钮点击回调方法
*/
override onClick(v ?: View) {
console.log("按钮被点击");
// 发送事件
this.comp.$emit("buttonclick");
}
}
</script>
<style>
</style>
@@ -0,0 +1,3 @@
{
"deploymentTarget": "9"
}
@@ -0,0 +1,212 @@
<template>
<view class="defaultStyles">
</view>
</template>
<script lang="uts">
/**
* 引用 iOS 系统库
* [可选实现,按需引入]
*/
import {
UIButton,
UIControl
} from "UIKit"
/**
* 引入三方库
* [可选实现,按需引入]
*
* 在 iOS 平台引入三方库有以下两种方式:
* 1、通过引入三方库framework 或者.a 等方式,需要将 .framework 放到 ./Frameworks 目录下,将.a 放到 ./Libs 目录下。更多信息[详见](https://uniapp.dcloud.net.cn/plugin/uts-plugin.html#ios-平台原生配置)
* 2、通过 cocoaPods 方式引入,将要引入的 pod 信息配置到 config.json 文件下的 dependencies-pods 字段下。详细配置方式[详见](https://uniapp.dcloud.net.cn/plugin/uts-ios-cocoapods.html)
*
* 在通过上述任意方式依赖三方库后,使用时需要在文件中 import:
* 示例:import { LottieAnimationView, LottieAnimation, LottieLoopMode } from 'Lottie'
*/
/**
* UTSiOS、UTSComponent 为平台内置对象,不需要 import 可直接调用其API[详见](https://uniapp.dcloud.net.cn/uts/utsios.html)
*/
import { UTSComponent } from "DCloudUTSFoundation"
//原生提供以下属性或方法的实现
export default {
data() {
return {
};
},
/**
* 组件名称,也就是开发者使用的标签
*/
name: "uts-button",
/**
* 组件涉及的事件声明,只有声明过的事件,才能被正常发送
*/
emits: ['buttonclick'],
/**
* 属性声明,组件的使用者会传递这些属性值到组件
*/
props: {
/**
* 字符串类型 属性:buttontext 需要设置默认值
*/
"buttontext": {
type: String,
default: "点击触发"
}
},
/**
* 组件内部变量声明
*/
/**
* 属性变化监听器实现
*/
watch: {
"buttontext": {
/**
* 这里监听属性变化,并进行组件内部更新
*/
handler(newValue : String, oldValue : String) {
this.$el.setTitle(newValue, for = UIControl.State.normal)
},
/**
* 创建时是否通过此方法更新属性,默认值为false
*/
immediate: false
},
},
/**
* 规则:如果没有配置expose,则methods中的方法均对外暴露,如果配置了expose,则以expose的配置为准向外暴露
* ['publicMethod'] 含义为:只有 `publicMethod` 在实例上可用
*/
expose: ['doSomething'],
methods: {
/**
* 对外公开的组件方法
* 在uni-app中调用组件方法,可以通过指定ref的方式,例如指定uts-button 标签的ref 为 button‘, 调用时使用:this.$refs["button"].doSomething('message');
*/
doSomething(paramA : string) {
// 这是组件的自定义方法
console.log(paramA, 'this is in uts-button component')
},
/**
* 内部使用的组件方法
*/
},
/**
* 组件被创建,组件第一个生命周期,
* 在内存中被占用的时候被调用,开发者可以在这里执行一些需要提前执行的初始化逻辑
* [可选实现]
*/
created() {
},
/**
* 对应平台的view载体即将被创建,对应前端beforeMount
* [可选实现]
*/
NVBeforeLoad() {
},
/**
* 创建原生View,必须定义返回值类型
* 开发者需要重点实现这个函数,声明原生组件被创建出来的过程,以及最终生成的原生组件类型
* [必须实现]
*/
NVLoad() : UIButton {
//必须实现
buttonClickListsner = new ButtonClickListsner(this)
let button = new UIButton()
button.setTitle(this.buttontext, for = UIControl.State.normal)
// 在 swift target-action 对应的方法需要以OC的方式来调用,那么OC语言中用Selector来表示一个方法的名称(又称方法选择器),创建一个Selector可以使用 Selector("functionName") 的方式。
const method = Selector("buttonClickAction")
if (buttonClickListsner != null) {
button.addTarget(buttonClickListsner!, action = method, for = UIControl.Event.touchUpInside)
}
return button
},
/**
* 原生View已创建
* [可选实现]
*/
NVLoaded() {
/**
* 通过 this.$el 来获取原生控件。
*/
this.$el.setTitle(this.buttontext, for = UIControl.State.normal)
},
/**
* 原生View布局完成
* [可选实现]
*/
NVLayouted() {
},
/**
* 原生View将释放
* [可选实现]
*/
NVBeforeUnload() { },
/**
* 原生View已释放,这里可以做释放View之后的操作
* [可选实现]
*/
NVUnloaded() {
},
/**
* 组件销毁
* [可选实现]
*/
unmounted() { }
/**
* 更多组件开发的信息详见:https://uniapp.dcloud.net.cn/plugin/uts-component.html
*/
}
/**
* 定义按钮点击后触发回调的类
* [可选实现]
*/
class ButtonClickListsner {
/**
* 如果需要在回调类或者代理类中对组件进行操作,比如调用组件方法,发送事件等,需要在该类中持有组件对应的原生类的对象。
* 组件原生类的基类为 UTSComponent,该类是一个泛型类,需要接收一个类型变量,该类型变量就是原生组件的类型。
*/
private component : UTSComponent<UIButton>
constructor(component : UTSComponent<UIButton>) {
this.component = component
super.init()
}
/**
* 按钮点击回调方法
* 在 swift 中,所有target-action (例如按钮的点击事件,NotificationCenter 的通知事件等)对应的 action 函数前面都要使用 @objc 进行标记。
* [可选实现]
*/
@objc buttonClickAction() {
console.log("按钮被点击")
// 发送事件
this.component.__$$emit("buttonclick");
}
}
/**
* 定义回调类或者代理类的实例
* [可选实现]
*/
let buttonClickListsner : ButtonClickListsner | null = null
</script>
<style>
</style>