小程序国际化是指将小程序的内容、功能和界面本地化,以适应不同语言和文化的用户。它是一种技术,可以帮助开发者将其小程序扩展到全球市场,从而获得更多的用户。
小程序国际化的主要目标是使用户能够在不同语言和文化中流畅地使用小程序。这意味着开发者必须考虑到不同语言和文化中的文字、图片、声音、功能和界面。
// 将文字本地化 let language = 'zh-CN'; // 语言 let text = { // 文字 'zh-CN': '你好', 'en-US': 'Hello' }; console.log(text[language]); // 输出你好或者Hello
为了实现小程序国际化,开发者必须对其代码进行重构:将所有文字、图片、声音和功能都放入一个单独的文件中(例如JSON文件);然后根据用户所选择的语言来加载相应的内容。上述代码片段显示了如何将文字本地化。
此外,开发者还必须考虑到不同语言之间的日期格式、数字格式和时间格式差异。例如:中国使用“年/月/日”作为日期格式;而在美国则使用“月/日/年”作为日期格式。
此外,小程序国际化还要考虑到不同语言之间的界面差异。例如:中国使用“左到右”作为书写方向;而在伊斯兰教徒国家则使用“从右到左”作为书写方向。
总之:小程序国际化是一个复杂耗时的过程;但是它也是一个重要步骤——它可以帮助开发者将其小程序扩展到其他市场并收集更多的电子商务流量。
miniprogram-i18n 的用法主要分为四部分。分别是:构建脚本与i18配置、i18n文本定义、WXML中的用法及JavaScript中的用法。
该方案目前需要依赖 Gulp 并且对源文件目录结构有一定的要求,需要确保小程序源文件放置在特定目录下(例如 src/ 目录)。
npm i -D gulp @miniprogram-i18n/gulp-i18n-locales @miniprogram-i18n/gulp-i18n-wxml
npm i -S @miniprogram-i18n/core
更多 Gulp 相关配置请参考 Gulp插件配置文档。
miniprogram-i18n 目前采用 JSON 文件对 i18n 文本进行定义。使用之前,需要在项目源文件下新建 i18n 目录。
目录结构如下:
├── dist // 小程序构建目录
├── gulpfile.js
├── node_modules
├── package.json
└── src // 小程序源文件目录
| ├── app.js
| ├── app.json
| ├── app.wxss
| ├── i18n // 国际化文本目录
| | ├── en-US.json
| | └── zh-CN.json
i18n 目录可以放置在源文件目录下的任意位置,例如可以跟 Page 或 Component 放在一起。但是需要注意的是,多个 i18n 目录下的文件在构建时会被合并打包,因此如果翻译文本有重复的 key 可能会发生覆盖。如果分开多个 i18n 目录定义需要自行确保 key 是全局唯一的。例如使用 page.index.testKey 这样的能确保唯一的名称。
下面我们定义文本:
// i18n/en-US.json
{
"plainText": "This is a plain text",
"withParams": "{value} is what you pass in"
}
// i18n/zh-CN.json
{
"plainText": "这是一段纯文本",
"withParams": "你传入的值是{value}"
}
定义好 i18n 文本之后,就可以在 WXML 文件里使用了。首先,需要在 WXML 文件对应的 JavaScript 文件里引入国际化运行时。
// pages/index/index.js
import { I18n } from "@miniprogram-i18n/core"
Component({
behaviors: [I18n]
})
注意:这里建议 Page 以及 Component 都采用 Component 构造器进行定义,这样可以使用 I18n 这个 Behavior。如果需要在 Page 构造上使用 I18n 则需要引入 I18nPage 代替 Page 构造器。
接着可以在 WXML 文件中获取预先定义好的 i18n 文本。
<!-- pages/index/index.wxml -->
<view>{{ t("plainText") }}</view>
<input placeholder="{{ t("withParams", {value}) }}"></input>
在 WXML 中使用 t 函数(或其他你指定的函数名)来获取文本。 t函数签名如下:
t(key: string, params: object)
它可以接受两个参数,第一个参数是 i18n 文本的 key,第二个参数是需要传入的插值对象(可以是从 AppService 传过来的值)。
在 JavaScript 里可以直接引用 @miniprogram-i18n/core 这个 NPM 包来获取翻译文本。
import { getI18nInstance } from "@miniprogram-i18n/core"
const i18n = getI18nInstance()
Component({
attached() {
const text = i18n.t("withParams", { value: "Test" })
console.log(text) // Test is what you pass in
i18n.setLocale("en-US")
}
})
同样的,在 i18n 实例上,还暴露了其他一些接口,例如获取当前语言、动态设置当前语言等。具体接口请参考 接口文档。
如果你的 JavaScript 对应的 WXML 里已经使用了国际化文本,换言之,即 Component 构造器已经引入了 I18n Behavior,那么所有的实例方法都会被直接挂载到 this 上,你可以通过 this 调用它们。
import { I18n } from "@miniprogram-i18n/core"
Component({
behaviors: [I18n],
attached() {
const text = this.t("withParams", { value: "Test" })
console.log(text) // Test is what you pass in
this.setLocale("en-US")
}
})
在编写完 i18n 文本并在 WXML 或 JavaScript 中调用之后,你需要运行 gulp 命令对 .wxml 文件进行转译并对 i18n 文本进行打包合并。
目前 miniprogram-i18n 仅支持纯文本及文本插值,后续会对其他 i18n 特性进行支持。
{
"key": "Inserted value: {value}"
}
i18n.t("key", { value: "Hello!" }) // Inserted value: Hello!
为了方便调用深层嵌套的对象,当前支持使用 . 点语法来访问对象属性。
{
"dotted": "Nested value is: { obj.nested.value }"
}
const value = {
obj: {
nested: {
value: "Catch you!"
}
}
}
i18n.t("dotted", value) // Nested value is: Catch you!
{
"key": "{gender, select, male {His inbox} female {Her inbox} other {Their inbox}}"
}
i18n.t("key", { gender: "male" }) // His inbox
i18n.t("key", { gender: "female" }) // Her inbox
i18n.t("key") // Their inbox
select 语句支持子语句文本插值:
{
"key": "{mood, select, good {{how} day!} sad {{how} day.} other {Whatever!}}"
}
i18n.t("key", { mood: "good", how: "Awesome" }) // Awesome day!
i18n.t("key", { mood: "sad", how: "Unhappy" }) // Unhappy day.
i18n.t("key") // Whatever!
注:select 语句支持子句嵌套 select 语句
其他尚未支持的特性有:
miniprogram-i18n API 是运行时在 JavaScript 侧操作 i18n 的接口。
在 app.js 调用 initI18n 来加载 i18n 文本并指定默认语言。若未进行指定,i18n运行时将默认从 /i18n/locales.js 中读取文本及配置。
// src/app.js
import { initI18n } from "@miniprogram-i18n/core"
import locales from "/i18n/locales.js"
initI18n(locales)
App({})
该接口会返回 I18n 运行时实例。
import { getI18nInstance } from "@miniprogram-i18n/core"
const i18n = getI18nInstance()
i18n.t("key")
以下五个接口用来获取或操作 I18n,均可在 I18n 实例或 拥有 I18n Behavior 的组件或 I18nPage 上进行调用。 通过组件直接访问成员函数:
import { I18n } from "@miniprogram-i18n/core"
Component({
behaviors: [I18n],
attached() {
this.t("key")
this.getLocale() // en-US
this.setLocale("zh-CN")
this.getFallbackLocale() // zh-CN
this.onLocaleChange((currentLocale) => {
console.log("Locale changed to", currentLocale)
})
}
})
或从 I18n 实例调用:
import { I18n } from "@miniprogram-i18n/core"
const i18n = getI18nInstance()
i18n.t("key")
i18n.getLocale() // en-US
i18n.setLocale("zh-CN")
i18n.getFallbackLocale() // zh-CN
i18n.onLocaleChange((currentLocale) => {
console.log("Locale changed to", currentLocale)
})
最主要的翻译函数,通过该函数可以获得预先定义的 i18n 文本。
获取当前设置的语言。默认语言应在 gulp 构建脚本中配置,详见 Gulp插件配置文档。
设置当前语言。该值应与 i18n 定义文件名相对应。
获取备选语言。该值在构建脚本中进行配置,一旦设置之后无法在运行时通过接口修改。详见 Gulp插件配置文档。
当前语言被修改时触发的事件回调。返回值 object,可通过返回值对象取消事件监听。
const event = i18n.onLocaleChange(() => {})
event.off()
miniprogram-i18n 在构建阶段依赖两个 Gulp 插件,分别是 @miniprogram-i18n/gulp-i18n-wxml 和 @miniprogram-i18n/gulp-i18n-locales,gulp-i18n-wxml 负责转译 wxml 文件中的 i18n 自定义语法,gulp-i18n-locales 则负责合并 i18n 定义文件,并进行预处理生成运行时所需的文件。
若使用 CLI 进行构建,则可忽略 Gulp 构建的配置。
因此在使用 i18n 的构建插件之前,需要先安装相关依赖。
npm i -D gulp @miniprogram-i18n/gulp-i18n-locales @miniprogram-i18n/gulp-i18n-wxml
依赖安装完成之后,需要建立 gulp 所需的配置并引入 i18n 构建插件。示例如下:
const gulpWxmlTransformer = require("@miniprogram-i18n/gulp-i18n-wxml")
const gulpLocalesLoader = require("@miniprogram-i18n/gulp-i18n-locales")
function transpileWxml() {
return src("src*.wxml")
.pipe(gulpWxmlTransformer())
.pipe(dest("dist/"))
}
function mergeAndGenerateLocales() {
return src("srci18n/*.json")
.pipe(gulpLocalesLoader({ defaultLocale: "zh-CN", fallbackLocale: "zh-CN" }))
.pipe(dest("dist/i18n/"))
}
更详细的配置请参考 examples。
该构建函数支持如下参数:
interface Options {
wxsPath: string,
wxsModuleName?: string,
i18nFunctionName?: string,
}
该构建函数支持如下参数:
interface Options {
wxsFileName?: string
jsFileName?: string
defaultLocale?: string
fallbackLocale?: string
}
#概览非兼容:自定义元素白名单现在在模板编译期间执行,应该通过编译器选项而不是运行时配置来配置。非兼容:特定 is prop 用法...
#概览下面是对变更的简要总结:API 已重命名,以便更好地与组件生命周期保持一致自定义指令将由子组件通过 v-bind="$attrs"更多...
XHTML 概要本教程已经向你教授了如何创建更严谨纯净的 HTML 页面。你已经知道所有的 XHTML 元素都必须被正确地嵌套,XHTML 必须...
HTML列表HTML 无序列表ul 元素表示无序列表。 ul 元素中的项目使用 li 元素表示。元素没有在HTML5中定义任何属性,并且您使用CSS...
嵌套错误可能引起的问题在我们使用各种浏览器时,时常发现即使不按照标准去嵌套也不会有大的错误问题,这就给我们带来了一个思考...