Skip to content

自定义消息格式

支持的版本

🆕 9.3+

消息格式语法中所述,Vue I18n 消息格式是原生的。

如果您想使用像 ICU 消息格式这样的消息格式,可以通过自己实现消息编译器来使用自定义格式。

WARNING

本主题需要理解 Vue I18n 消息格式编译以及格式如何解析。

WARNING

此功能是实验性的。将来可能会出现破坏性更改或被移除。

消息编译器实现

您可以通过实现具有以下接口的函数来创建消息编译器。

以下是 TypeScript 类型定义:

ts
export declare type MessageCompiler<Message = string, MessageSource = string | ResourceNode> = (message: MessageSource, context: MessageCompilerContext) => MessageFunction<Message>;

以下是一个使用 intl-messageformat 实现的消息编译器示例,用于支持 ICU 消息格式。

ts
import IntlMessageFormat from 'intl-messageformat'

import type { MessageCompiler, CompileError, MessageContext } from 'vue-i18n'

export const messageCompiler: MessageCompiler = (
  message,
  { locale, key, onError }
) => {
  if (typeof message === 'string') {
    /**
     * 您可以通过缓存策略或其他记忆化在这里进一步优化消息编译器的性能
     */
    const formatter = new IntlMessageFormat(message, locale)
    return (ctx: MessageContext) => {
      return formatter.format(ctx.values)
    }
  } else {
    /**
     * 对于 AST。
     * 如果您想支持它,
     * 需要使用捆绑插件将 `json`、`yaml` 等本地化消息转换。
     */
    onError && onError(new Error('不支持 AST') as CompileError)
    return () => key
  }
}

消息编译器注册

在实现消息编译器后,按如下方式将 messageCompiler 选项设置为 createI18n,然后您可以对 messages 选项使用自己的消息格式:

ts
import { createI18n } from 'vue-i18n'
import { messageCompiler } from './compilation'

const i18n = createI18n({
  legacy: false,
  locale: 'en',
  messageCompiler,
  messages: {
    en: {
      hello: 'hello world!',
      greeting: 'hi, {name}!',
      photo: `You have {numPhotos, plural,
        =0 {no photos.}
        =1 {one photo.}
        other {# photos.}
      }`
    }
  }
})

// 以下是您的其他操作...
// ...

参考资料

在实现消息编译器时,我们建议您阅读并理解编译代码

INFO

您可以在 examples/message-format 找到下面教程的代码。