App开发——国际化多语言的实现

1.引言

我们当前正处于一个全球化的世界,所以我们开发的 App 也会有很大的概率,需要满足国际化多语言的需求。今天刚好看到有个小伙伴遇到了这个需求需要实现,这里就借此机会,简单讲解一下,在 YonBuilder移动开发 技术中,如果去实现一个支持国际化多语言的 App 应用开发。

2.开发思路逻辑

多语言国际化,说白了就是将页面的文字内容显示为指定的国家语音。根据这个核心诉求,我们可以将整体功能拆分成以下的几个功能点需求:

2.1包含多语言内容的资源文件

这个是物料基础,用于切换到对应的语言后,可以正确的显示对应内容

2.2页面使用模板渲染构建

可以使用vue、react或者doT等模板渲染框架,目的是一旦切换了系统语言后,页面可以动态的进行快速切换

2.3编写多语言切换逻辑

包括获取当前多语言版本、设置多语言版本、读取多语言版本、读取多语言内容、页面实时渲染等逻辑

3实战演练:一个简单的多语言Demo

3.1创建一个应用项目

PS: 还未学习创建的新手同学,可跳转【2023最新】超详细图文保姆级教程:App开发新手入门(1),进行基础学习后再回来继续。

创建一个应用,并在本地使用 YonStudio 开发工具打开

在这里插入图片描述

3.2创建一个页面,用于多语言内容展示

我们直接修改 ./html/main.html 页面,下面仅讲解涉及的主要功能代码,全部代码可去我的gitee仓库:https://gitee.com/T0T/yonbuilder-app-demos下载。

说明:本页面的数据绑定实现方式是通过引用 vue 框架来实现的,将最新的 vue.js 代码下载到本地j进行保存, 本次演示引用的是 vue3 框架代码

https://unpkg.com/vue@3.4.14/dist/vue.global.prod.js

PS: 通过 src 直接引用 cdn 链接也是可以的,不过在实际开发中,因为网络网速的原因,还是放在本地直接引用的方式,运行效率会更好。

在这里插入图片描述

页面内通过 script 标签引用 vue 文件

<head><script src="../script/vue.global.prod.js"></script><style>html,body {height: 100%;width: 100%;}....代码省略</style>
</head>

编写页面内容,对于需要做国际化的文字内容,使用模板变量来进行标识,及 下面代码块中的 {{ }},这些是vue的基本语法规则,这里就不多说了。

<body id="app"><div class="panel"><div class="title">{{ title }}</div><div class="row"><span class="row-label">{{ nameLabel }}:</span><span class="row-content">{{ name }}</span></div><div class="row"><span class="row-label">{{ ageLabel }}:</span><span class="row-content">{{ age }}</span></div></div><div class="panel" style="margin-top: 50px;"><div class="title">多语言切换操作</div><div class="flex-row"><div class="btn" tapmode="cilck-active" :class="{active: i18nKey==='zh-CN'}" @click="handleSetI18n('zh-CN')">中文</div><div class="btn" :class="{active: i18nKey==='en-US'}" tapmode="cilck-active" @click="handleSetI18n('en-US')">英文</div></div></div>
</body>

在运行逻辑部分,我们先初始化 vue 示例对象,然后在 生命周期事件 mounted 方法内,调用内部的 initPageWithVue() 方法进行页面的初始化逻辑操作。

// 页面内容国际化
addI18nChangeListener(this.parsePageWithI18n);
this.parsePageWithI18n();

上面代码实现了2个业务功能

  • 国际化语音切换时间监听

addI18nChangeListener 方法是添加了国际化语音切换的事件监听,当在其他页面切换语言后,当前页面通过该监听获取该事件,然后即可调用 parsePageWithI18n 方法,进行页面内容的国际化切换。
该方法是封装在 i18n.js 文件内,当前页面通过 script 脚本方式引入,具体的内容,等后面我们讲解 i18n.js 文件时再展开。

<script type="text/javascript" src="../script/i18n.js"></script>
  • 页面内容进行初始的国际化处理

parsePageWithI18n 方法,主要逻辑是负责将当前页面的内容,转化成当前正在使用的国际化语言内容。

对当前页面的文本内容进行初始变量值的国际化处理,可以看到在 parsePageWithI18n 方法中,我们通过调用 parseWord 函数,对文本内容进行国际化内容转换。这个 parseWord 函数也是我们自己编写后封装在 i18n.js 文件中的,后面我们会做详细介绍。

 parsePageWithI18n() {this.i18nKey = getI18n();this.title = parseWord('人物简介');this.nameLabel = parseWord('姓名');this.name = parseWord('张三');this.ageLabel = parseWord('年龄');
}

当前页面我们还设置了一个切换国际化语音的方法 handleSetI18n,用于模拟实际业务中的国际化语音切换。

handleSetI18n(i18nSign){if(!i18nSign) return;setI18n(i18nSign);
}

在实际业务中,根据产品需求,有可能在 App 应用中,显示的提供语言切换按钮,像本次 App 这样。也有可能直接获取手机操作系统的本地语言,然后 App 进行动态的适配。原来大致都是一样的,获取操作系统的本地语言,可以使用引擎提供的 api.language 方法

在这里插入图片描述

3.3编写多语言逻辑脚本文件

我们需要根据页面中需要进行国际化的语言内容,进行整理,然后编写一个最终版本的 国际化资源文件。当然此方法并不是唯一的实现逻辑,我们也可以根据需要,将文件内容按不同的维度拆分成多个文件进行相应的读取处理,这里我们主要讲解基本的实现思路,就不进行过多的扩展了。

我们实际 demo 应用中的 ./script/i18n.js 文件,就是我们最终封装的国际化多语言服务脚本。其中我们主要定义了以下几个主要的功能逻辑。

    1. 多语言映射数据体

根据实际业务需要,我们可以增加自己的多语言适配版本。

PS: 当前使用中文内容作为 map 中的 key,主要是为了方便在具体的引用页面中,可以直观的了解当前的文本内容的含义。开发者也可以使用英文或其他文本内容作为标识,这个并不强制唯一。

var i18nMapData =  {'多语言国际化示例': {'zh-CN': '多语言国际化示例','en-US': 'i18n Demo'},'人物简介': {'zh-CN': '人物简介','en-US': 'profile'},'姓名': {'zh-CN': '姓名','en-US': 'name'},'张三': {'zh-CN': '张三','en-US': 'three'},'年龄': {'zh-CN': '年龄','en-US': 'age'},}
    1. 获取当前应用的多语言版本标识

PS: 数据的本地化存储有多重方式,本处代码中,使用 api.setPrefsapi.getPrefs 函数方法进行数据的本地化存储读取的主要原因是 api.getPrefs 函数方法支持同步读取(及下面代码的 sync: true ),大多数的本地读取是异步的,如果开发者经验不足,容易产生一些不必要的逻辑错误。

/*** 读取国际化语言的判断标识(采用同步策略)* @returns */
function getI18n() {var i18nStr = api.getPrefs({sync: true,key: 'i18n'});if(!i18nStr) {i18nStr = api.language;setI18n(i18nStr);}return i18nStr;
}
    1. 设置当前应用的多语言版本标识

这里我们在进行本地设置的同时,向外部发送了一个 i18nChange 的消息事件,主要的目的帮助已经加载完毕的页面,通过监听该事件,实现页面内容的动态国际化切换。

/*** 存储国际化语言的判断标识* @param {String} i18nSign */
function setI18n(i18nSign) {// 新的系统语言标识var i18nStr = i18nSign ? i18nSign : api.language;// 本地缓存api.setPrefs({key: 'i18n',value: i18nStr});// 发送同步通知,用于一些已经初始化的页面进行动态切换(按业务需要,非必须)api.sendEvent({name:'i18nChange',extra: {i18nSign: i18nStr}})
}
    1. 国际化多语言切换的事件监听逻辑封装

需要国际化的页面,通过调用本方法,即添加了事件监听。页面通过将自己内部的国际化处理函数传入当前方法,当事件触发时,通过回调机制触发函数执行,从而实现了自动化的国际化内容处理。

/*** 添加i18n改变的页面监听* @param {Function} callBack 触发事件后的回调函数*/function addI18nChangeListener(callBack) {api.addEventListener({name:'i18nChange'}, function(ret){if(typeof callBack === 'function') {callBack(ret.value);}})
}

3.4最终呈现的效果

在这里插入图片描述

4.总结

以上只是一个简单的多语言Demo,意在示范整体的实现思路逻辑,在实际的应用开发中,开发者需要根据实际的业务逻辑进行相应的变通修改。

比如上面只是展示了页面内的静态内容的替换,那么对于一些交互的提示信息等动态内容并未展示。其实他们的内在逻辑是一样的,就是在内容展示的前一个周期内,将需要展示的文字内容动态替换为对应的语言内容即可。

另外我们在实际开发中,会向后端服务器发送请求,接收服务端的响应数据,并根据业务逻辑进行展示(正确的提示或者错误的提示等)。如果客户端展示的内容是由服务端提供的,那么这里有2种实现方式。

一种是前端将当前系统语音版本信息发送给服务端,由服务端负责返回对应的多语言内容;
另一种是将服务端返回的提示信息整理成固定的多语言版本文件,然后存储到前端应用中,由前端自行完成语言切换;

这两种方法都OK,具体实践中可以由前后端的开发人员一起沟通确定即可。

其他的比如切换系统语言后,如何实现页面的实时刷新,这里我们可以使用 事件监听或者跨页面执行脚本等支持消息传递的方法去实现事件触发即可。

注意事项: 因为各语种同一个意思的文字长度不相同,有的会很长,所以在实现了内容文字的动态国际化功能后,建议去每一个页面都去进行实际的切换对比查看,对于某些文字超出限定范围的情况,需要单独的定制化的去优化(如调整样式或者翻译的文本内容),以期达到最佳效果。

提醒: 通常我们进行国际化,只需要国际化我们开发负责实现的那些固定的文字内容即可,这里有两个关键词:开发负责实现、固定内容。进一步的解释就是,系统功能面板(比如由操作系统提供的一些显示内容,不需要我们开发处理,通常会跟随操作系统的语言进行动态切换的。另外相对于固定内容,动态内容通常是由服务端返回,并且大部分内容很难在开发阶段预判,所以尽量返回内容的国际化的工作由服务端负责,或者就不需要支持动态内容的国际化。

PS: 在代码编写过程中,我使用了 var 等老式的原生js语法编写,当前市场上虽然大部分手机系统都已经支持了 ES6 的新语法,但还存在一定量的手机系统的浏览器引擎并不支持,所以如果我们进行商业应用开发的话,这一点还是要注意的。另外,本次 demo 使用的是 html 混合方式进行的页面开发,如果使用 AVM 框架进行开发,则没有这方面的问题,因为 AVM 框架本身含有 build 的编译过程,同时 AVM 框架本身就是采用的类vue语法规则,所以可以去除引入vue框架的步骤,并可以对 ES6等新语法进行兼容性处理,反而开发起来变得更加简单。

道阻且长,祝顺利!加油 -~~!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/415548.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

UVa1318/LA2797 Monster Trap

题目链接 本题是2003年ICPC亚洲区域赛会津(日本)赛区的H题 题意 给出一些线段障碍&#xff0c;你的任务是判断怪物能否逃到无穷远处。如下图所示&#xff0c;左图无法逃出&#xff0c;右图的可以逃出。 输入包含多组数据。每组数据第一行为整数n&#xff08;1≤n≤100&#xf…

zabbix其他配置

自动发现 zabbix server 主动的去发现所有的客户端&#xff0c;然后将客户端的信息登记在服务端上。 缺点是如果定义的网段中的主机数量多&#xff0c;zabbix server 登记耗时较久&#xff0c;且压力会较大。 systemctl disable --now firewalld setenforce 0 hostnamectl se…

【unity学习笔记】语音驱动blendershape

1.导入插件 https://assetstore.unity.com/packages/tools/animation/salsa-lipsync-suite-148442 1.选择小人&#xff0c;点击添加组件 分别加入组件&#xff1a; SALSA EmoteR Eyes Queue Processor&#xff08;必须加此脚本&#xff09;&#xff1a;控制前三个组件的脚本。…

vulnhub靶机Chill_Hack

下载地址&#xff1a;Chill Hack: 1 ~ VulnHub 主机发现 目标176 端口扫描 服务扫描 直接去看web 先扫一下 有几个有点问题 看着好像命令执行 看来没错直接反弹shell 还有还白名单&#xff1f; bash也不能用 那就用php吧 whoami|php -r $sockfsockopen("192.168.21.13…

微信这个费用,终于降低了

大家好&#xff0c;我是小悟 这个费用降低了&#xff0c;这对于广大小程序开发者来说无疑是一个好消息。这一举措不仅可以降低开发者的成本&#xff0c;还有助于激发更多的创新和创业激情。 对于广大小程序开发者来说&#xff0c;这也是一个福音&#xff0c;因为他们可以降低开…

使用 Jest 和 Supertest 进行接口端点测试实例详解

如何创建测试是一件困难的事。网络上有许多关于测试的文章&#xff0c;却从来不告诉你他们是如何开始创建测试的。 所以&#xff0c;今天我将分享我在实际工作中是如何从头开始创建测试的。希望能够对你提供一些灵感。 目录&#xff1a; 使用 Express 创建一个应用 使用 Mon…

Mysql:重点且常用的操作和理论知识整理 ^_^

目录 1 基础的命令操作 2 DDL 数据库定义语言 2.1 数据库操作 2.2 数据表操作 2.2.1 创建数据表 2.2.2 修改和删除数据表 2.2.3 添加外键 3 DML 数据库操作语言 3.1 插入语句(INSERT) 3.2 修改语句(UPDATE) 3.3 删除语句 3.3.1 DELETE命令 3.3.2 TRUNCATE命令 4 …

vue基于Spring Boot共享单车租赁报修信息系统

共享单车信息系统分为二个部分&#xff0c;即管理员和用户。该系统是根据用户的实际需求开发的&#xff0c;贴近生活。从管理员处获得的指定账号和密码可用于进入系统和使用相关的系统应用程序。管理员拥有最大的权限&#xff0c;其次是用户。管理员一般负责整个系统的运行维护…

【文本到上下文 #5】:RNN、LSTM 和 GRU

一、说明 欢迎来到“完整的 NLP 指南&#xff1a;文本到上下文 #5”&#xff0c;这是我们对自然语言处理 &#xff08;NLP&#xff09; 和深度学习的持续探索。从NLP的基础知识到机器学习应用程序&#xff0c;我们现在深入研究了神经网络的复杂世界及其处理语言的深刻能力。 在…

BACCM业务模型核心概念

业务分析概念一览 现在&#xff0c;我们将商业&#xff08;业务&#xff09;分析核心概念模型™&#xff08;BACCM™&#xff09;中六个核心概念&#xff08;core concept&#xff09;整理如下&#xff1a; Change&#xff0c;the act of transformation in response to a nee…

FaFu--练习复盘--1

1、输出图形及二维数组应用 1.1.输出图形 描述 编写程序打印n行如下图形&#xff0c;其中1≤n≤500。 输入用例 7 输出用例 具体实现 #include"stdio.h" int main(){int n,i,j;scanf("%d",&n);for(i 1; i< n;…

mysql-实战案例 (超详细版)

&#x1f389;欢迎您来到我的MySQL基础复习专栏 ☆* o(≧▽≦)o *☆哈喽~我是小小恶斯法克&#x1f379; ✨博客主页&#xff1a;小小恶斯法克的博客 &#x1f388;该系列文章专栏&#xff1a;重拾MySQL &#x1f379;文章作者技术和水平很有限&#xff0c;如果文中出现错误&am…