微信小程序国际化探索实现(附源码地址)

随着小程序应用越来越广泛,国际化支持逐渐成了刚需。

官方文档给出了一个 国际化方案 ,但觉得配置起来稍微有点复杂,对项目结构还有一定的要求。如果是旧项目改动成本太大,遂决定自己实现一个小程序国际化方案。

源码地址:https://github.com/cachecats/miniprogram-i18n

一、项目结构

整体目录结构如下图:

  • assets 存放资源文件,如图片
  • constants 存放项目中用到的常量
  • i18n 存放语言文件,中文是 zh-CN.js 英文是 en-US.js ,如果还需要支持其他语言再建一个 js 即可
  • pages 存放业务逻辑代码
  • utils 存放工具类。LangUtils 是封装的国际化工具类。

二、工具类封装及语言包准备

2.1 语言包准备

i18n 目录下的各语言包结构要一致,即对象的 key 保持一致, value 是对应的语言文本。

建议每个小模块分为一个对象,单个对象的内容不宜过多。

zh-CN.js

export default {
 common: {
 language: '语言',
 chinese: '中文',
 english: '英语',
 },
 tabBarTitles: ['主页', '论坛', '我的'],
 navTitle: {
 home: '主页',
 forum: '论坛',
 mine: '我的',
 setting: '设置'
 },
 home: {
 motto: '我们宁愿拥有一个不完美的变革,也不愿看到一个没有希望的未来',
 respect: '致勇者',
 getUserInfo: '获取头像昵称'
 },
 forum: {
 forumModule: '我是论坛模块',
 tip: '下面是一个组件,用来展示组件的国际化配置'
 },
 comment: {
 title: '评论组件',
 msg: '网络一线牵,珍惜这段缘'
 },
 mine: {
 title: '这是我的页面',
 toNewPage: '跳转到新页面'
 },
 setting: {
 title: '我是设置页面'
 }
}

en-US.js

export default {
 common: {
 language: 'Language',
 chinese: 'Chinese',
 english: 'English',
 },
 tabBarTitles: ['Home', 'Forum', 'Mine'],
 navTitle: {
 home: 'Home',
 forum: 'Forum',
 mine: 'Mine',
 setting: 'setting'
 },
 home: {
 motto: 'We would rather have an imperfect change than see a hopeless future',
 respect: 'to warrior',
 getUserInfo: 'Get avatar nickname'
 },
 forum: {
 forumModule: 'I am forum module',
 tip: 'The following is a component to show the international configuration of the component'
 },
 comment: {
 title: 'Comment Components',
 msg: 'The network leads, cherish this relationship'
 },
 mine: {
 title: 'This is mine page',
 toNewPage: 'Go to new page'
 },
 setting: {
 title: 'I am setting page'
 }
}

2.2 工具类 LangUtils 封装

工具类 LangUtils 封装了国际化所需的所有方法,包括获取当前语言、设置语言、获取当前语言的资源文件、设置 TabBar 、设置 NavigationBar 等方法。

实现思路是把当前设置的语言存在小程序提供的 storage中,每次项目初始化时从 storage 中读取语言,如果没有读到则默认设置为中文。

然后在每个页面或组件的 data 中将页面需要用到的文本资源引入进来, wxml 中使用 data 中绑定的变量展示文字。同时在生命周期的 onShow 方法中重新读取当前语言并设置 data ,使得每次改变语言都能正确的加载语言包。

先看 LangUtils 的代码:

import zh from '../i18n/zh-CN.js'
import en from '../i18n/en-US.js'
import Constants from '../constants/Constants';

export default{

 //初始化语言设置。在 app.js 里调用这个方法。
 initLang(){
 //先获取是不是已存在语言的设置
 let lang = wx.getStorageSync('lang')
 if(!lang){
  //如果不存在,设置默认语言为中文
  this.setLang(Constants.langCN)
 }
 },

 //设置语言
 setLang(lang){
 try{
  wx.setStorageSync('lang', lang)
 }catch(e){
  console.log('设置语言失败', e)
 }
 },

 //获取语言设置
 getLang(){
 try{
  let lang = wx.getStorageSync('lang')
  return lang;
 }catch(e){
  console.log('获取语言设置失败', e)
 }
 },

 //获取当前语言下的资源文件
 getLangSrc(){
 let lang = this.getLang();
 if(lang === Constants.langCN){
  return zh;
 } else if(lang === Constants.langEN){
  return en;
 }else{
  return zh;
 }
 },

 //设置 NavigationBarTitle
 setNavigationBarTitle(title){
 wx.setNavigationBarTitle({
  title: title
 })
 },

 /**
 * 设置 tabBar。因为 tabBar 是在 app.json 里写死的,需要使用 wx.setTabBarItem
 * 循环设置 tabBar
 */
 setTabBarLang(){
 let tabBarTitles = this.getLangSrc().tabBarTitles;
 console.log('tabBarTitles', tabBarTitles)
 tabBarTitles.forEach((item, index) => {
  console.log(item, index)
  wx.setTabBarItem({
  index: index,
  text: item,
  success: (res) => {
   console.log('setTabBarItem success', res)
  },
  fail: (err) => {
   console.log('setTabBarItem fail', err)
  }
  });
 });
 },
}

先引入中文和英文的语言包,以便根据当前语言设置返回对应的资源包。

Constants 是对常量的封装,这里保存的是中英文编码标识。

Constants.js

/**
 * 保存项目中的常量
 */
export default{
 //中文编码
 langCN: 'zh-CN',
 //英文编码
 langEN: 'en-US',
}

需要注意的是 tabBar 的处理,因为 tabBar 是写死在 app.json 中的,不能动态的改变文本,所以每次语言改变只能用小程序暴露出来的 wx.setTabBarItem 方法循环的设置 tabBar

至此前期的准备工作已经做完啦,接下来对具体的页面和组件做处理。

三、项目使用

需要改动三个地方

  • app.js 初始化语言
  • xxx.jsdata 添加语言属性,并在 onShow 生命周期方法中调用 setData 重新设置语言
  • xxx.wxml 中的文本替换为 data 里绑定的变量

3.1 app.js 初始化语言

在项目入口文件 app.js 中做初始化。

//初始化国际化语言设置
import LangUtils from './utils/LangUtils'

App({
 onLaunch: function () {
 // 国际化的初始化
 LangUtils.initLang();
 LangUtils.setTabBarLang();
 }
})

3.2 Page 页面的国际化 js 中使用

js 中的使用分三步:

首先引入 LangUtils.js

然后在 data 中定义变量 lang ,通过 ... 对象的解构赋值,把语言文件中对应模块定义的变量都赋值给 lang ,方便调用。如果是 settings 模块,可以这样写: lang: {...LangUtils.getLangSrc().settings} 。也可以只写个空对象: lang: {} ,然后在 onShow() 方法里对 lang 赋值。

onShow() 生命周期方法里,更新 lang 的值,以防语言被改变。如果需要设置小程序标题,则再调用 LangUtils.setNavigationBarTitle() 方法。

// pages/setting/setting.js
import LangUtils from '../../utils/LangUtils'
let langSrc = LangUtils.getLangSrc()

Page({

 /**
 * 页面的初始数据
 */
 data: {
 lang: {
  ...langSrc.setting
 }
 },

 /**
 * 生命周期函数--监听页面显示
 */
 onShow: function () {
 this.setLanguage();
 },

 /**
 * 重新设置语言
 */
 setLanguage() {
 langSrc = LangUtils.getLangSrc();
 this.setData({
  lang: {
  ...langSrc.setting
  }
 })
 // 设置 NavigationBarTitle
 LangUtils.setNavigationBarTitle(langSrc.navTitle.setting);
 }
})

wxml 中使用

wxml 里比较简单,跟普通的变量使用方法一样。

<view class="setting-container">
	<text class="title">{{lang.title}}</text>
</view>

3.2 Component 组件的国际化

ComponentPage 国际化基本上相同,但因为生命周期方法不同,稍微有点区别。

Coponentsthis.setLanguage() 在生命周期的 pageLifetimesshow 方法中调用。

// pages/forum/components/comment.js
import LangUtils from '../../../../utils/LangUtils'
let langSrc = LangUtils.getLangSrc();

Component({
 data: {
 lang: {
  ...langSrc.comment
 }
 },

 pageLifetimes: {
 // 组件所在页面的生命周期函数
 show: function () {
  console.log('page show---')
  this.setLanguage();
 },
 },

 /**
 * 组件的方法列表
 */
 methods: {
 /**
  * 重新设置语言
  */
 setLanguage() {
  langSrc = LangUtils.getLangSrc();
  this.setData({
  lang: {
   ...langSrc.comment
  }
  })
 }
 }
})

3.3 切换语言

切换语言放在 demo 的 home 页面中。用户更改语言后要调用 LangUtils.setLang 更改语言值,还要调用 LangUtils.setTabBarLang 重新设置 tabBar 的文本。

切换后的效果

//index.js
//获取应用实例
const app = getApp()

import Constants from '../../constants/Constants'
// 获取对应语言的资源文件
import LangUtils from '../../utils/LangUtils'
let langSrc = LangUtils.getLangSrc();

// 语言选项
const LANGUAGE_OPTIONS = [{
 key: Constants.langCN,
 value: '中文'
 },
 {
 key: Constants.langEN,
 value: 'English'
 }
]

Page({
 data: {
 // 通过解构赋值将 common 和 home 下的变量赋值给 lang。最好每个模块建一个对象
 // 对象里的属性不宜过多,否则在 data 里放入太多内容会影响性能,用到什么放什么。
 lang: {
  ...langSrc.common,
  ...langSrc.home
 },
 langOptions: LANGUAGE_OPTIONS,
 index: 0
 },

 onLoad: function () {
 // 根据当前语言设置 picker 默认选中的值
 let lang = LangUtils.getLang();
 this.setData({
  index: lang === Constants.langCN ? 0 : 1
 })
 },
 onShow: function () {
 //每次 onShow 重新设置语言,以防语言更新
 this.setLanguage();
 },

 getUserInfo: function (e) {
 console.log(e)
 app.globalData.userInfo = e.detail.userInfo
 this.setData({
  userInfo: e.detail.userInfo,
  hasUserInfo: true
 })
 },

 /**
 * 选择语言变化回调函数
 */
 onLanguageChange(e) {
 const index = e.detail.value
 console.log(e)
 this.setData({
  index: index
 })
 // 更改语言
 LangUtils.setLang(this.data.langOptions[index].key);
 // 重新设置 tabBar 的语言
 LangUtils.setTabBarLang();
 this.setLanguage();
 },

 /**
 * 重新设置语言
 */
 setLanguage() {
 langSrc = LangUtils.getLangSrc();
 this.setData({
  lang: {
  ...langSrc.common,
  ...langSrc.home
  }
 })
 // 设置 NavigationBarTitle
 LangUtils.setNavigationBarTitle(langSrc.navTitle.home);
 }
})

四、总结

代码乍一看还挺多的,但优点是不用引入第三方模块,也不用按要求改项目结构。其实把前期的准备工作做完后,后期维护起来还是很方便的。

当然这个方案还有可优化的地方,比如每个页面的 onShow 方法里都要执行相似的逻辑,以后有时间会做优化。

项目地址:https://github.com/cachecats/miniprogram-i18n

到此这篇关于微信小程序国际化探索实现(附源码地址)的文章就介绍到这了,更多相关小程序国际化内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 微信小程序 数组(增,删,改,查)等操作实例详解

    微信小程序 数组(增,删,改,查)等操作 最近在做一个小程序的demo.由于不向后台请求数据,所以就涉及到对本地数据的操作,也遇到了一些坑,本文就以数组的增删改查为例,给新手分享一些经验. 首先这是原始数据,json的数组. 我们尝试对改数据进行操作,同时渲染到页面. 1,数据的添加 在获取到表单的数据后,自己组装一个对象,然后通过push()的方法添加一条数据,注意push的数据的index是+1的,也就是说原本数组中index依次为0,1,2,新增加的就是3,依次类推. 如果想在前面插入数据

  • 微信小程序 时间格式化(util.formatTime(new Date))详解

    微信小程序 时间格式化 微信小程序虽然还在内测,但是已经火的不行.赶紧看看.记录学习路上的点点滴滴. 获取时间直接用 Date.now() 得到一串数字.如下图: 获取格式化的时间用 util.formatTime(new Date) util是微信官方demo里面的提供的工具:如下代码 function formatTime(date) { var year = date.getFullYear() var month = date.getMonth() + 1 var day = date.

  • c语言10个经典小程序

    [程序1] 题目:有1.2.3.4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? 1.程序分析:可填在百位.十位.个位的数字都是1.2.3.4.组成所有的排列后再去 掉不满足条件的排列. 2.程序源代码: 复制代码 代码如下: main() { int i,j,k; printf("\n"); for(i=1;i<5;i++) /*以下为三重循环*/ for(j=1;j<5;j++) for (k=1;k<5;k++) { if (i!=k&&a

  • 微信小程序 for 循环详解

    1,wx:for 在组件上使用wx:for控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件.默认数组的当前项的下标变量名默认为index,数组当前项的变量名默认为item 事例如下: wxml文件: <view wx:for="{{items}}"> {{index}}: {{item:one}} </view> js文件: Page({ items:[{ one: "test1", },{ one: "test2&qu

  • 微信小程序 参数传递详解

    微信小程序的推出,无疑将会在移动互联网行业里再次掀起风浪. 有人会质疑小程序会不会火, 会不会火我不知道, 看微信的用户量即可明白一切. 微信小程序-参数传递 这里我找到两种小程序上的参数传递方式,为了方便,我单独拿出来和大家分享下. 一.通过事件进行参数传递 先来看眼小程序对事件的定义: #什么是事件? 这里是列表文本事件是视图层到逻辑层的通讯方式. 这里是列表文本事件可以将用户的行为反馈到逻辑层进行处理. 这里是列表文本事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数

  • 微信小程序 页面跳转传参详解

    微信小程序 页面跳转传参,做微信小程序必定会用的这样的功能,这里就记录下本人学习实现代码资料. 刚接触微信小程序,多里面的语法和属性还不怎么聊解,如有不多的地方希望各位大神多多指教.今天来说下微信小程序怎么跳转和传参,话不多说直接上代码. 实现的功能是给列表增加点击功能传参到下一页: 代码如下: <import src="../WXtemplate/headerTemplate.wxml"/> <view> <!--滚动图--> <view&g

  • 微信小程序 跳转页面的两种方法详解

    微信小程序 跳转页面 小程序页面有2种跳转,可以在wxml页面或者js中: 1,在wxml页面中: <navigator url="../index/index">跳转到新页面</navigator> <navigator url="../index/index" open-type="redirect">在当前页打开</navigator> <navigator url="../i

  • 微信小程序 传值取值的几种方法总结

    微信小程序 传值取值 小程序里常见的取值有以下几种,一个完整的项目写下来,用到的概率几乎是100%. 列表index下标取值 页面传值 form表单取值 1. 列表index下标取值 实现方式是:data-index="{{index}}"挖坑及e.currentTarget.dataset.index来填坑即可 1.1 生成值 <image src="../../../images/icon_delete.png" /><text>删除&l

  • 微信小程序 触控事件详细介绍

    微信小程序 触控事件: 微信小程序的"事件"挺有意思.看了说明文档后发现它的功能很全,事件可以向父节点传递,而且打印这个事件的信息很透明,调试起来应该非常方便. 接下来把文档copy过来 原文地址:https://mp.weixin.qq.com/debug/wxadoc/dev/framework/view/wxml/event.html >>>什么是事件 事件是视图层到逻辑层的通讯方式. 事件可以将用户的行为反馈到逻辑层进行处理. 事件可以绑定在组件上,当达到触发

  • 微信小程序国际化探索实现(附源码地址)

    随着小程序应用越来越广泛,国际化支持逐渐成了刚需. 官方文档给出了一个 国际化方案 ,但觉得配置起来稍微有点复杂,对项目结构还有一定的要求.如果是旧项目改动成本太大,遂决定自己实现一个小程序国际化方案. 源码地址:https://github.com/cachecats/miniprogram-i18n 一.项目结构 整体目录结构如下图: assets 存放资源文件,如图片 constants 存放项目中用到的常量 i18n 存放语言文件,中文是 zh-CN.js 英文是 en-US.js ,如

  • 微信小程序实现天气预报功能(附源码)

    前言 最近在学小程序开发,刚好学到天气预报功能的制作,于是给大家分享下. 效果图 天气API获取 这里我用的是和风天气的API,打开官网注册或者登陆你的账号 进入控制台,新建应用 这是刚刚我们创建好的应用,点击添加KEY 选择WebAPI 这注册好我们的API了 微信小程序后台域名配置 登陆小程序后台,分别点击开发和开发设置 点击修改,将我们API的域名添加到request合法域名里面https://free-api.heweather.net 页面代码 .wxml <view class=&quo

  • 微信小程序 天气预报开发实例代码源码

    微信小程序 天气预报 实例主要功能 自动定位所在城市 根据所定位的城市获取天气信息 显示未来几天的天气情况 查看当天天气的详情信息 先看效果图 微信小程序-天气 首页 微信小程序-天气 详情页 思路及编码部份自动定位所在城市 wx.getLocation:通过官方文档的API中可以看到wx.getLocation可以获取到当前的地理位置和速度,不过获取到的地理位置只是经纬度,而不是真正的城市名称,但我们可以根据这个经纬度来获取城市名称等信息(需要用到第三方接口),再通过城市名称和城市ID获取对应

  • 微信小程序实现表单验证源码

    本文实例为大家分享了微信小程序实现表单验证的具体代码,供大家参考,具体内容如下 效果图 点击预约设计弹出表单 城市,面积不能输入,只能选择 点击位置获取当前定位 源码: Wxml <!--pages/designerList/designerDetail.wxml--> <view>     <view class='tc m_t20'>     <image src='{{urlhttp + designerDetail.thumb}}' class='imgl

  • 详解微信小程序工程化探索之webpack实战

    前言 微信小程序因为其便捷的使用方式,以极快的速度传播开来吸引了大量的使用者.市场需求急剧增加的情况下,每家互联网企业都想一尝甜头,因此掌握小程序开发这一技术无疑是一名前端开发者不可或缺的技能.但小程序开发当中总有一些不便一直让开发者诟病不已,主要表现在: 初期缺乏方便的npm包管理机制(现阶段确实可以使用npm包,但是操作确实不便) 不能使用预编译语言处理样式 无法通过脚本命令切换不同的开发环境,需手动修改对应环境所需配置(常规项目至少具备开发与生产环境) 无法将规范检查工具结合到项目工程中(

  • 微信小程序将字符串生成二维码图片的操作方法

    最近接到这样一个需求,需要在小程序里将十几位随机字符串转换为二维码的形式展示.公众号中(另一终端)调用JSSDK扫一扫功能,去扫描小程序生成的二维码.得到字符串,然后进行接下来的逻辑处理. 下面记录的是小程序中生成二维码图片这一操作,用的是原文作者改版后的生成二维码工具weapp-qrcode.js(demo的众多文件中只需将util下的这个文件拷贝到自己项目中),可在原文地址里clone demo. 截图(copy原文) 使用 1.页面wxml中放置绘制二维码的canvas 加入点击改变二维码

  • 微信小程序长按识别二维码的几种情况分析

    目录 一.image标签 + show-menu-by-longpress=“{{true}}” 二.wx.previewImage 三. web-view 支持长按识别的码 补充:扫码中有几个可配置的参数注意下 总结 小程序中的图片已支持长按识别了,总结一下几种情况下: 一.image标签 + show-menu-by-longpress=“{{true}}” <image src="{{qrcode}}" mode="widthFix" show-menu

  • uniapp实现微信小程序的电子签名效果(附demo)

    目录 1.标签和样式 2.横屏切换 3.绘图 3.1.初始化数据会吧? 3.2.触摸开始时获取起点,会吧? 3.3.触摸移动获取路径点,会吧? 3.4.触摸结束,将未绘制的点清空防止对后续路径产生干扰,简单吧? 3.5.绘制笔迹,没得问题吧? 4.扫尾处理 画布可以做很多事情,比如可以绘图,也可以做海报.在这里只是想拿它来的实现亲笔签名,开启不一样的亲笔签名姿势. 开发框架:uniapp开发语言:vue2展示平台:微信小程序(实际可以兼容多个平台) 标签和样式没什么好说的,这里绘制了简单的页面,

  • 详解Java豆瓣电影爬虫——小爬虫成长记(附源码)

    以前也用过爬虫,比如使用nutch爬取指定种子,基于爬到的数据做搜索,还大致看过一些源码.当然,nutch对于爬虫考虑的是十分全面和细致的.每当看到屏幕上唰唰过去的爬取到的网页信息以及处理信息的时候,总感觉这很黑科技.正好这次借助梳理Spring MVC的机会,想自己弄个小爬虫,简单没关系,有些小bug也无所谓,我需要的只是一个能针对某个种子网站能爬取我想要的信息就可以了.有Exception就去解决,可能是一些API使用不当,也可能是遇到了http请求状态异常,又或是数据库读写有问题,就是在这

  • vue实现的微信机器人聊天功能案例【附源码下载】

    本文实例讲述了vue实现的微信机器人聊天功能.分享给大家供大家参考,具体如下: 先看效果: 实现过程: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>HTML5模拟微信聊天界面</title> <style> /**重置标签默认样式*/ * { margin: 0; padding: 0; list-style: none; fo

随机推荐