WeChat Applet Internationalization Exploration (with Source Address)

As applets become more and more widely used, international support has become a new requirement.

The official document gives one Internationalization Programs However, it feels a little complicated to configure and has certain requirements for the project structure.If the cost of changing an old project is too high, you decide to internationalize a small program yourself.

Source address: github.com/cachecats/m...

I. Project Structure

The overall directory structure is as follows:

  • assets holds resource files, such as pictures
  • Constants store constants used in projects
  • i18n stores language files, zh-CN.js in Chinese and en-US.js in English, if you need to support another JS in other languages
  • pages hold business logic code
  • utils holds the tool class.LangUtils is an internationalized tool class for encapsulation.

2. Tool class encapsulation and language pack preparation

2.1 Language Pack Preparation

The structure of each language pack in the i18n directory should be consistent, that is, the key of the object should be consistent and the value should be the corresponding language text.

It is recommended that each small module be divided into one object and that the contents of a single object not be too large.

zh-CN.js

export default {
  common: {
    language: 'language',
    chinese: 'Chinese',
    english: 'English',
  },
  tabBarTitles: ['homepage', 'forum', 'My'],
  navTitle: {
    home: 'homepage',
    forum: 'forum',
    mine: 'My',
    setting: 'Set up'
  },
  home: {
    motto: 'We would rather have an imperfect change than a hopeless future',
    respect: 'A hero',
    getUserInfo: 'Get your avatar nickname'
  },
  forum: {
    forumModule: 'I'm a forum module',
    tip: 'Here is a component that shows the internationalized configuration of the component'
  },
  comment: {
    title: 'Comment Component',
    msg: 'Network lead, cherish this relationship'
  },
  mine: {
    title: 'This is my page',
    toNewPage: 'Jump to a new page'
  },
  setting: {
    title: 'I'm setting up the page'
  }
}
Copy Code

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'
  }
}
Copy Code

2.2 Tool Class LangUtils Encapsulation

The tool class LangUtils encapsulates all the methods required for internationalization, including acquiring the current language, setting the language, acquiring resource files for the current language, setting the TabBar, setting the NavigationBar, and so on.

The idea is to provide an existing applet for the currently set language storage In, each time the project is initialized, the language is read from the store, and if not, it is set to Chinese by default.

The text resources needed for the page are then introduced into the data of each page or component, and the text is displayed in wxml using the variables bound in the data.At the same time, re-read the current language and set the data in the onShow method of the life cycle so that each language change loads the language pack correctly.

First look at the LangUtils code:

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

export default{

  //Initialize language settings.Call this method in app.js.
  initLang(){
    //Get the setting of whether the language already exists first
    let lang = wx.getStorageSync('lang')
    if(!lang){
      //If not, set the default language to Chinese
      this.setLang(Constants.langCN)
    }
  },

  //Set Language
  setLang(lang){
    try{
      wx.setStorageSync('lang', lang)
    }catch(e){
      console.log('Failed to set language', e)
    }
  },

  //Get Language Settings
  getLang(){
    try{
      let lang = wx.getStorageSync('lang')
      return lang;
    }catch(e){
      console.log('Failed to get language settings', e)
    }
  },

  //Get the resource file in the current language
  getLangSrc(){
    let lang = this.getLang();
    if(lang === Constants.langCN){
      return zh;
    } else if(lang === Constants.langEN){
      return en;
    }else{
      return zh;
    }
  },

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

  /**
   * Set tabBar.Because tabBar was written in app.json, you need to use wx.setTabBarItem
   * Loop setting 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)
        }
      });
    });
  },
}
Copy Code

The Chinese and English language packs are introduced first to return the corresponding resource packs according to the current language settings.

Constants are encapsulations of constants, where English and Chinese coded identifiers are stored.

Constants.js

/**
 * Save Constants in Project
 */
export default{
  //Chinese encoding
  langCN: 'zh-CN',
  //Encoding in English
  langEN: 'en-US',
}
Copy Code

Note the processing of tabBar, because tabBar is written to death in app.json and cannot dynamically change the text, so each language change can only be set by the wx.setTabBarItem method loop exposed by the applet.

Preparations have been completed up to this point, and then specific pages and components will be processed.

3. Project Use

Three places need to be changed

  • app.js Initialization Language
  • data for xxx.js adds language properties and calls setData in the onShow life cycle method to reset the language
  • Replace text in xxx.wxml with variables bound in data

3.1 app.js Initialization Language

Initialize in the project entry file app.js.

//Initialize international language settings
import LangUtils from './utils/LangUtils'

App({
  onLaunch: function () {
    // Initialization of Internationalization
    LangUtils.initLang();
    LangUtils.setTabBarLang();
  }
})
Copy Code

3.2 Internationalization of Page Pages

Using in js

There are three steps to using js:

  1. First introduce LangUtils.js

  2. Then, the variable Lang is defined in the data, and the corresponding module-defined variables in the language file are assigned to Lang through the deconstruction assignment of the.. object for easy invocation.If it is a settings module, you can write as follows: lang: {...LangUtils.getLangSrc().settings}.You can also just write an empty object: lang: {} and assign a value to the Lang in the onShow() method.

  3. In the onShow() lifecycle method, update the lang value to prevent language changes.If you need to set the title of the applet, call the LangUtils.setNavigationBarTitle() method again.

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

Page({

  /**
   * Initial data for page
   */
  data: {
    lang: {
      ...langSrc.setting
    }
  },

  /**
   * Lifecycle Functions--Monitor Page Display
   */
  onShow: function () {
    this.setLanguage();
  },

   /**
   * Reset Language
   */
  setLanguage() {
    langSrc = LangUtils.getLangSrc();
    this.setData({
      lang: {
        ...langSrc.setting
      }
    })
    // Set NavigationBarTitle
    LangUtils.setNavigationBarTitle(langSrc.navTitle.setting);
  }
})
Copy Code

Using in wxml

wxml is simpler and uses the same variables as normal.

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

3.2 Internationalization of Component Components

Component s are basically the same as Page internationalization, but they are slightly different due to different lifecycle approaches.

this.setLanguage() of Coponents is called in the show method of pageLifetimes in the life cycle.

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

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

  pageLifetimes: {
    // Life cycle function of the page on which the component resides
    show: function () { 
      console.log('page show---')
      this.setLanguage();
    },
  },

  /**
   * List of methods for components
   */
  methods: {
    /**
     * Reset Language
     */
    setLanguage() {
      langSrc = LangUtils.getLangSrc();
      this.setData({
        lang: {
          ...langSrc.comment
        }
      })
    }
  }
})
Copy Code

3.3 Switching languages

The switch language is placed on demo's home page.After the user changes the language, he calls LangUtils.setLang to change the language value and LangUtils.setTabBarLang to reset the text of the tabBar.

Effect after switching

//index.js
//Get Application Instances
const app = getApp()

import Constants from '../../constants/Constants'
// Get the resource file for the corresponding language
import LangUtils from '../../utils/LangUtils'
let langSrc = LangUtils.getLangSrc();

// Language Options
const LANGUAGE_OPTIONS = [{
    key: Constants.langCN,
    value: 'Chinese'
  },
  {
    key: Constants.langEN,
    value: 'English'
  }
]

Page({
  data: {
    // Variables under common and home are assigned to lang by deconstruction assignment.It's best to build one object per module
    // Don't put too many attributes in the object, or putting too much content in the data will affect performance, what to use and what to put.
    lang: {
      ...langSrc.common,
      ...langSrc.home
    },
    langOptions: LANGUAGE_OPTIONS,
    index: 0
  },

  onLoad: function () {
    // Set picker default selected value according to current language
    let lang = LangUtils.getLang();
    this.setData({
      index: lang === Constants.langCN ? 0 : 1
    })
  },
  onShow: function () {
    //Each onShow resets the language to prevent language updates
    this.setLanguage();
  },

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

  /**
   * Select Language Change Callback Function
   */
  onLanguageChange(e) {
    const index = e.detail.value
    console.log(e)
    this.setData({
      index: index
    })
    // Change Language
    LangUtils.setLang(this.data.langOptions[index].key);
    // Reset tabBar language
    LangUtils.setTabBarLang();
    this.setLanguage();
  },

  /**
   * Reset Language
   */
  setLanguage() {
    langSrc = LangUtils.getLangSrc();
    this.setData({
      lang: {
        ...langSrc.common,
        ...langSrc.home
      }
    })
    // Set NavigationBarTitle
    LangUtils.setNavigationBarTitle(langSrc.navTitle.home);
  }
})
Copy Code

4. Summary

At first glance, there's a lot of code, but the advantage is that you don't have to introduce third-party modules or change the project structure as required.In fact, it is very convenient to maintain the later period after the preparatory work has been completed.

Of course, there are other things that can be optimized for this scheme, such as performing similar logic in each page's onShow method and having time to do so later.

Project Address: github.com/cachecats/m...

Tags: github network JSON encoding

Posted on Sun, 17 May 2020 20:37:32 -0400 by andy_b42