meetfun-i18n
v1.2.14
Published
基于 vue-i18n 的 uni-app 国际化解决方案,支持 Vue2/Vue3,支持多语言缓存、远程语言包、动态加载等功能
Maintainers
Readme
meetfun-i18n
基于 vue-i18n 的 uni-app 国际化解决方案,支持 Vue2/Vue3,支持多语言缓存、远程语言包、动态加载等功能。
特性
- 🚀 开箱即用 - 简单的 API 设计,快速集成到 uni-app 项目
- 🎭 Vue2/Vue3 双支持 - 同时支持 Vue2 + vue-i18n@8 和 Vue3 + vue-i18n@9
- 📦 多语言缓存 - 自动缓存语言包到本地,支持离线使用
- 🔄 动态语言包 - 支持从远程服务器动态加载语言包
- 🎯 缺失键上报 - 自动收集并上报缺失的翻译键
- 🔧 变量替换 - 支持复杂的变量替换,包括嵌套对象访问
- 🎨 代理模式 - 内置国际化代理功能,轻松处理枚举翻译
- 📱 跟随系统 - 支持跟随系统语言自动切换
- 💪 TypeScript - 完整的类型定义支持
安装
# 使用 pnpm
pnpm add meetfun-i18n
# Vue2 项目还需要安装
pnpm add vue@^2.7.0 vue-i18n@^8.0.0
# Vue3 项目需要安装
pnpm add vue@^3.0.0 vue-i18n@^9.0.0引入方式
根据你的项目类型选择对应的引入方式:
// Vue3 项目(默认)
import { createMeetFunI18n } from 'meetfun-i18n'
// Vue2 项目
import { createMeetFunI18n } from 'meetfun-i18n/vue2'快速开始
1. 准备语言包文件
创建语言包文件,例如 src/locales/zh-Hans.json:
{
"TALENTS": {
"欢迎": "欢迎",
"你好,{name}": "你好,{name}"
}
}2. 创建 API 函数
创建获取语言包的 API 函数,例如 src/api/translate.ts:
import { translateRequest } from '@/utils/request'
import type { LangDictResponse, QueryLangDictColdDataParams } from '@meetfun/i18n'
/**
* 获取热数据(常用翻译)
*/
export const queryLangDictHotData = (params: { systemCode: string }) => {
return translateRequest.post<LangDictResponse>(
'/api/translate/langDict/queryLangDictHotData',
params,
)
}
/**
* 获取冷数据(缺失翻译上报)
*/
export const queryLangDictColdData = (params: QueryLangDictColdDataParams) => {
return translateRequest.post<LangDictResponse>(
'/api/translate/langDict/queryLangDictColdData',
params,
{ custom: { loading: false } },
)
}3. 初始化 i18n
在 src/locales/index.ts 中初始化:
import { createMeetFunI18n } from '@meetfun/i18n'
import { queryLangDictHotData, queryLangDictColdData } from '@/api/translate'
import zhHans from './zh-Hans.json'
import zhHant from './zh-Hant.json'
import en from './en.json'
// 基础语言包
const baseMessages = {
'zh-Hans': zhHans,
'zh-Hant': zhHant,
en: en,
}
// API 配置
const apiConfig = {
queryLangDictHotData,
queryLangDictColdData,
}
// 创建 i18n 实例
const i18nInstance = createMeetFunI18n(baseMessages, apiConfig, {
defaultLocale: 'zh-Hans',
defaultLangDictDomainCode: 'TALENTS',
systemCode: 'TALENTS_STUDENT',
localeCacheKey: 'APP_LOCALE_SETTING',
langDictCacheKey: 'APP_LANG_DICT_CACHE',
cacheMaxAge: 365 * 24 * 60 * 60 * 1000, // 365天
reportDelay: 5000, // 5秒
})
export default i18nInstance4. 在 Vue 应用中使用
在 main.ts 中安装:
import { createSSRApp } from 'vue'
import i18nInstance from './locales'
export function createApp() {
const app = createSSRApp(App)
// 安装 vue-i18n
app.use(i18nInstance.getI18n())
return {
app,
}
}5. 在组件中使用
<template>
<view>
<!-- 使用 $t 函数翻译 -->
<text>{{ $t('欢迎') }}</text>
<!-- 带变量的翻译 -->
<text>{{ $t('你好,{name}', { name: '张三' }) }}</text>
</view>
</template>
<script setup lang="ts">
import i18nInstance from '@/locales'
// 直接使用 i18n 实例
const welcomeText = i18nInstance.$t('欢迎')
// 带参数
const greetingText = i18nInstance.$t('你好,{name}', { name: '李四' })
</script>API 文档
createMeetFunI18n(baseMessages, apiConfig, userConfig?)
创建 i18n 实例的工厂函数。
参数:
baseMessages:Record<string, any>- 基础语言包apiConfig:ApiConfig- API 配置queryLangDictHotData: 获取热数据的函数queryLangDictColdData: 获取冷数据的函数
userConfig?:Partial<I18nConfig>- 用户配置(可选)defaultLocale?: 默认语言,默认'zh-Hans'defaultLangDictDomainCode?: 默认领域代码,默认'TALENTS'systemCode?: 系统代码localeCacheKey?: 语言设置缓存键,默认'APP_LOCALE_SETTING'langDictCacheKey?: 语言包缓存键,默认'APP_LANG_DICT_CACHE'cacheMaxAge?: 缓存最大有效期(毫秒),默认 365 天reportDelay?: 上报延迟时间(毫秒),默认 5000ms
返回: MeetFunI18n 实例
MeetFunI18n 实例方法
$t(key, params?)
翻译函数,支持变量替换。
const text = i18nInstance.$t('你好,{name}', { name: '张三' })fetchLangDictHotData()
获取远程语言包(热数据)。
await i18nInstance.fetchLangDictHotData()switchLocale(locale)
切换语言。
import { LANGUAGE_OPTIONS_CONFIGURATION } from '@meetfun/i18n'
// 切换到英文
i18nInstance.switchLocale(LANGUAGE_OPTIONS_CONFIGURATION.EN)
// 跟随系统
i18nInstance.switchLocale(LANGUAGE_OPTIONS_CONFIGURATION.FOLLOW_SYSTEM)getCurrentLocale()
获取当前语言。
const locale = i18nInstance.getCurrentLocale() // 'zh-Hans'getHeaderLang()
获取用于请求头的语言标识。
const headerLang = i18nInstance.getHeaderLang() // 'zh_cn'updateI18nMessages(langDictData, saveToCache?)
更新语言包。
await i18nInstance.updateI18nMessages(newLangData, true)flushMissingKeys()
立即上报所有缓存的缺失翻译键。
await i18nInstance.flushMissingKeys()getTranslationKeysStats()
获取翻译键统计信息。
const stats = i18nInstance.getTranslationKeysStats()
console.log(stats.missingKeys) // { TALENTS: 10 }
console.log(stats.usedKeys) // { TALENTS: 100 }clearLangDictCache()
清除语言包缓存。
i18nInstance.clearLangDictCache()高级功能
国际化代理 - 枚举翻译
使用代理模式轻松处理枚举翻译:
import i18nInstance from '@/locales'
// 定义角色枚举翻译映射
const roleNamesMap = {
PRODUCING_AREA: 'role.PRODUCING_AREA',
PRESENTATION_AREA: 'role.PRESENTATION_AREA',
STORE_MANAGER: 'role.STORE_MANAGER',
}
// 创建代理对象
const roleNames = i18nInstance.createI18nProxy(roleNamesMap)
// 直接访问即可获得翻译后的文本
console.log(roleNames.PRODUCING_AREA) // '产区'
console.log(roleNames.STORE_MANAGER) // '店长'
// 也可以使用 createEnumI18nProxy(语义化别名)
const statusNames = i18nInstance.createEnumI18nProxy({
ACTIVE: 'status.active',
INACTIVE: 'status.inactive',
})变量替换
支持嵌套对象访问的变量替换:
const template = '用户 {user.name} 的年龄是 {user.age}'
const params = {
user: {
name: '张三',
age: 25,
},
}
const result = i18nInstance.interpolateVariables(template, params)
console.log(result) // '用户 张三 的年龄是 25'条件编译支持
在不同的编译环境使用不同的系统代码:
let systemCode = 'TALENTS_STUDENT'
// #ifdef SYSTEM_S
systemCode = 'TALENTS_STUDENT'
// #endif
// #ifdef SYSTEM_M
systemCode = 'TALENTS_MANAGEMENT_APP'
// #endif
const i18nInstance = createMeetFunI18n(baseMessages, apiConfig, {
systemCode,
})语言包数据格式
服务器返回的语言包格式:
{
"zh_cn": {
"TALENTS": {
"欢迎": "欢迎",
"你好": "你好"
}
},
"zh_hk": {
"TALENTS": {
"欢迎": "歡迎",
"你好": "你好"
}
},
"en": {
"TALENTS": {
"欢迎": "Welcome",
"你好": "Hello"
}
}
}库会自动将 zh_cn 转换为 zh-Hans,zh_hk 转换为 zh-Hant。
最佳实践
1. 在 App.vue 中加载远程语言包
<script setup lang="ts">
import { onLaunch } from '@dcloudio/uni-app'
import i18nInstance from '@/locales'
onLaunch(() => {
// 加载远程语言包
i18nInstance.fetchLangDictHotData()
})
</script>2. 在页面卸载时上报缺失键
<script setup lang="ts">
import { onUnmounted } from 'vue'
import i18nInstance from '@/locales'
onUnmounted(() => {
// 立即上报缺失的翻译键
i18nInstance.flushMissingKeys()
})
</script>3. 语言切换组件
<template>
<view>
<picker :value="langIndex" :range="langOptions" @change="handleLangChange">
<view>{{ langOptions[langIndex] }}</view>
</picker>
</view>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { LANGUAGE_OPTIONS_CONFIGURATION } from '@meetfun/i18n'
import i18nInstance from '@/locales'
const langOptions = ['跟随系统', '简体中文', '繁體中文', 'English']
const langIndex = ref(0)
const handleLangChange = (e: any) => {
const index = e.detail.value
langIndex.value = index
const langMap = [
LANGUAGE_OPTIONS_CONFIGURATION.FOLLOW_SYSTEM,
LANGUAGE_OPTIONS_CONFIGURATION.ZH_HANS,
LANGUAGE_OPTIONS_CONFIGURATION.ZH_HANT,
LANGUAGE_OPTIONS_CONFIGURATION.EN,
]
i18nInstance.switchLocale(langMap[index])
uni.showToast({
title: '切换成功',
icon: 'success',
})
}
</script>Vue2 支持
本库完整支持 Vue2 项目,详细使用方式请查看:Vue2 使用指南
关键区别:
- Vue2 项目从
meetfun-i18n/vue2引入 - Vue3 项目从
meetfun-i18n引入(默认) - API 使用方式完全一致
版本要求
- Vue2: Vue 2.7+ 和 vue-i18n 8.x
- Vue3: Vue 3.x 和 vue-i18n 9.x
注意事项
- uni 对象依赖:本库依赖 uni-app 的
uni全局对象,仅适用于 uni-app 项目。 - API 配置:必须提供
queryLangDictHotData和queryLangDictColdData两个 API 函数。 - 缓存策略:语言包缓存默认有效期为 365 天,可根据需求调整。
- 缺失键上报:使用防抖机制,默认延迟 5 秒上报,避免频繁请求。
- Vue 版本选择:确保使用正确的引入路径(Vue2 使用
/vue2子路径)。
类型定义
本库提供完整的 TypeScript 类型定义,支持类型提示和检查。
import type {
I18nConfig,
ApiConfig,
LangDictResponse,
TranslationKeysStats,
// ... 更多类型
} from '@meetfun/i18n'License
MIT
作者
meetfun
