Skip to content

createReactiveI18n

基于响应式系统的国际化函数,支持语言切换时的自动更新。

函数签名

typescript
function createReactiveI18n(
  config: I18nConfig,
  deps: I18nDeps
): I18nInstance

interface I18nConfig {
  /** 默认语言 */
  defaultLocale: string
  /** 回退语言 */
  fallbackLocale?: string
  /** 语言包 */
  messages: I18nMessages
}

interface I18nDeps {
  /** 创建响应式对象 */
  createReactive: CreateReactive
  /** 控制台日志函数 */
  log: (...args: any[]) => void
  /** 控制台警告函数 */
  warn: (...args: any[]) => void
}

前置依赖

依赖参数

参数名类型说明
deps.createReactiveCreateReactive创建响应式对象的函数,用于实现语言切换的自动更新
deps.log(...args: any[]) => void日志输出函数,用于记录语言切换等操作
deps.warn(...args: any[]) => void警告输出函数,用于记录翻译缺失等警告信息

环境要求

  • createReactive: 需要先导入 createReactive 函数
bash
# 确保已安装相关依赖
npm install shared

参数

参数名类型必填说明
configI18nConfig国际化配置对象
config.defaultLocalestring默认语言代码
config.fallbackLocalestring回退语言代码,缺失翻译时使用
config.messagesI18nMessages语言包对象,键为语言代码,值为翻译对象
depsI18nDeps环境依赖,包含响应式函数和日志函数

返回值

类型说明
I18nInstance国际化实例,包含翻译函数和语言管理方法

工作原理

  1. 响应式状态管理:使用 createReactive 创建响应式的语言状态
  2. 嵌套键解析:支持 user.profile 等点分隔的嵌套键结构
  3. 参数替换:支持 {name} 等占位符的参数替换
  4. 回退机制:当前语言缺失翻译时自动使用回退语言
  5. 订阅通知:语言变化时自动通知所有订阅者
  6. 动态语言包:支持运行时添加新的语言包

核心特性

  • 语言切换时所有翻译自动更新
  • 支持嵌套对象结构的翻译键
  • 智能回退到备用语言
  • 参数化翻译支持
  • 响应式订阅机制

异常

错误类型触发条件错误信息
Error缺少默认语言defaultLocale is required
Error语言包为空messages is required and cannot be empty
Error默认语言不存在Default locale "xxx" not found in messages

完整示例

typescript
import { createReactiveI18n } from 'zcw-shared/reactive/createReactiveI18n'
import { createReactive } from 'zcw-shared/reactive/createReactive'

// 创建国际化实例
const i18n = createReactiveI18n({
  defaultLocale: 'zh-CN',
  fallbackLocale: 'en',
  messages: {
    'zh-CN': {
      hello: '你好',
      welcome: '欢迎 {name}',
      user: {
        profile: '个人资料',
        settings: '设置'
      },
      navigation: {
        home: '首页',
        about: '关于我们'
      }
    },
    'en': {
      hello: 'Hello',
      welcome: 'Welcome {name}',
      user: {
        profile: 'Profile',
        settings: 'Settings'
      },
      navigation: {
        home: 'Home',
        about: 'About Us'
      }
    },
    'ja': {
      hello: 'こんにちは',
      welcome: '{name}さん、ようこそ',
      user: {
        profile: 'プロフィール',
        settings: '設定'
      },
      navigation: {
        home: 'ホーム',
        about: '私たちについて'
      }
    }
  }
}, {
  createReactive,
  log: console.log,
  warn: console.warn
})

// 基础翻译
console.log(i18n.t('hello'))  // 输出: 你好

// 参数化翻译
console.log(i18n.t('welcome', { name: '张三' }))  // 输出: 欢迎 张三

// 嵌套键翻译
console.log(i18n.t('user.profile'))  // 输出: 个人资料
console.log(i18n.t('navigation.home'))  // 输出: 首页

// 切换语言
i18n.setLocale('en')
console.log(i18n.t('hello'))  // 输出: Hello
console.log(i18n.t('welcome', { name: 'John' }))  // 输出: Welcome John

// 订阅语言变化
const unsubscribe = i18n.subscribe(() => {
  console.log('语言已切换到:', i18n.locale)
  // 更新 UI 显示
  updateUI()
})

// 动态添加语言包
i18n.addMessages('fr', {
  hello: 'Bonjour',
  welcome: 'Bienvenue {name}',
  user: {
    profile: 'Profil',
    settings: 'Paramètres'
  }
})

// 检查语言支持
console.log(i18n.hasLocale('fr'))  // true
console.log(i18n.getLocales())  // ['zh-CN', 'en', 'ja', 'fr']

// 获取当前语言的所有翻译
const currentMessages = i18n.getMessages()
console.log(currentMessages)  // 当前语言的完整翻译对象

// 清理订阅
unsubscribe()

实际应用场景

typescript
// Vue 组件中使用
import { createReactiveI18n } from 'zcw-shared/reactive/createReactiveI18n'
import { createReactive } from 'zcw-shared/reactive/createReactive'

const i18n = createReactiveI18n(config, { createReactive, log: console.log, warn: console.warn })

// 在组件中订阅语言变化
export default {
  setup() {
    const locale = ref(i18n.locale)
    
    // 订阅语言变化
    i18n.subscribe(() => {
      locale.value = i18n.locale
    })
    
    return {
      locale,
      t: i18n.t,
      setLocale: i18n.setLocale
    }
  }
}

// React Hook 中使用
function useI18n() {
  const [locale, setLocale] = useState(i18n.locale)
  
  useEffect(() => {
    const unsubscribe = i18n.subscribe(() => {
      setLocale(i18n.locale)
    })
    
    return unsubscribe
  }, [])
  
  return {
    locale,
    t: i18n.t,
    setLocale: i18n.setLocale
  }
}

高级用法

typescript
// 自定义翻译函数
function createCustomT(i18n: I18nInstance) {
  return (key: string, params?: Record<string, any>) => {
    const result = i18n.t(key, params)
    
    // 添加自定义逻辑
    if (result === key) {
      console.warn(`Missing translation for key: ${key}`)
    }
    
    return result
  }
}

// 批量翻译
function translateBatch(i18n: I18nInstance, keys: string[]) {
  return keys.reduce((acc, key) => {
    acc[key] = i18n.t(key)
    return acc
  }, {} as Record<string, string>)
}

// 语言检测
function detectLanguage(): string {
  const browserLang = navigator.language || navigator.languages?.[0]
  return browserLang.startsWith('zh') ? 'zh-CN' : 'en'
}

// 自动初始化
const i18n = createReactiveI18n({
  defaultLocale: detectLanguage(),
  fallbackLocale: 'en',
  messages: messages
}, deps)

基于响应式系统的国际化解决方案,让语言切换变得简单而高效!