This is the third day of my participation in the August More text Challenge. For details, see: August More Text Challenge

0 x00 preface

This article will systematically explain the element internationalization solution implementation, the project built-in 51 languages. The SRC /locale directory stores the language configuration file, internationalization method, text format, and so on. The following will explain one by one.

0x01 Internationalization scheme

Element’s internationalization solution is implemented by customization without introducing third-party plug-ins such as Vue-i18n. It is compatible with VUe-I18N, which makes it very convenient to use.

πŸ“ src/locale/lang

The default language is zh-cn. The SRC /locale/lang/ zh-cn. Js file returns data in JSON format, which contains the description translation of each component.

export default {
  el: {
    // Component select selector
    select: {
      loading: 'Loading'.noMatch: 'No matching data'.noData: 'No data'.placeholder: 'Please select'
    },
    // ...}}Copy the code

To use other languages, add a language configuration file in the directory.

πŸ“ƒ SRC/locale/format. Js

Provides string template functions that support index or named keyword arguments. For the code implementation, see NPM /string-template.

// Core method

/** * String template function, support index or named keyword arguments *@param {String} String Template string *@param {Array} . * args parameter@return {String}  Format text * */
function template(string, ... args) {
  const RE_NARGS = /(%|)\{([0-9a-zA-Z_]+)\}/g;
  if (args.length === 1 && typeof args[0= = ="object") {
    args = args[0]; 
  }

  if(! args || ! args.hasOwnProperty) { args = {}; }return string.replace(RE_NARGS, (match, prefix, i, index) = > {
    let result; 
    if (string[index - 1= = ="{" && string[index + match.length] === "}") { 
      return i;
    } else {
      result = hasOwn(args, i) ? args[i] : null;
      if (result === null || result === undefined) {
        return "";
      } 
      returnresult; }}); }Copy the code

πŸ“ƒ SRC/locale/index. Js

Index.js provides three methods: use, t, and i18n for language switching Settings, internationalization handling, i18n plug-in compatibility, and customization. See the annotated source code for details.

The use method parameter is used to configure language content for language switching. If the parameter is empty, the simplified Chinese characters (zh-cn) are used by default.

import defaultLang from 'element-ui/src/locale/lang/zh-CN'; 
let lang = defaultLang; // Default language
 
// Language switch
export const use = function(l) {
  lang = l || lang;
};
 
Copy the code

The I18N method is used for compatibility with external plug-in methods and the introduction of custom processing methods. The implementation of the i18nHandler method is designed to be compatible with the external plug-in [email protected].

If a custom handler is passed in, the i18nHandler method implementation is overridden.


// i18nHandler is an i18n handler. This logic is intended to be compatible with external i18n schemes such as [email protected].
let i18nHandler = function() {
  // If the plug-in [email protected] is introduced, the $t method will be mounted on the Vue prototype.
  // i18nHandler will try to find the $t function in the Vue prototype by default,
  const vuei18n = Object.getPrototypeOf(this || Vue).$t;
  // The method vuei18n exists
  if (typeof vuei18n === 'function'&&!!!!! Vue.locale) {// Merge the language configuration content
    if(! merged) { merged =true;
      Vue.locale(
        Vue.config.lang,
        deepmerge(lang, Vue.locale(Vue.config.lang) || {}, { clone: true})); }// Use vuei18n for internationalization
    return vuei18n.apply(this.arguments); }};// i18n processing methods (support to introduce custom methods)
export const i18n = function(fn) {
  i18nHandler = fn || i18nHandler;
}; 

Copy the code

The t method is used for component internationalization processing. It finds the corresponding copy from the language configuration according to the passed path, and then formats it in combination with options.

// The default language is Simplified Chinese
import defaultLang from 'element-ui/src/locale/lang/zh-CN'; 
// String template function
import Format from './format';

// Is equivalent to the template() method
const format = Format(Vue);
let lang = defaultLang; // Default language

let i18nHandler = function() {
    // ...
}

// Internationalize the processing method
export const t = function(path, options) { 

  // To be compatible with external i18N schemes such as [email protected] or custom methods
  let value = i18nHandler.apply(this.arguments);
  // External methods are preferred
  if(value ! = =null&& value ! = =undefined) return value;

  // Path interception gets the attribute hierarchy
  const array = path.split('. ');
  // Translate the content
  let current = lang;

  // Translate the content hierarchically based on the attributes in the path
  for (let i = 0, j = array.length; i < j; i++) {
    const property = array[i];
    value = current[property];
    // console.log(property, value);
    if (i === j - 1) {
      // Format the content
      // value gets the translation content parameters passed to the options component
      return format(value, options);
    }
    if(! value)return ' ';
    current = value;
  }
  return ' ';
};
Copy the code

0x02 Component internationalized reference

Next, we will introduce the internationalization function through the examples of Select and Pagination components.

Function introduction

SRC /mixins/locale.js introduces the t method in SRC /locale/index.js and provides it to component pages in mixin mode.

import { t } from 'element-ui/src/locale';

export default {
  methods: {
    t(. args) {
      return t.apply(this, args); }}};Copy the code

You can see the internationalization processing logic in the Select component source code.

import Locale from 'element-ui/src/mixins/locale'; 

export default {
    mixins: [Locale], 
    name: 'ElSelect'.componentName: 'ElSelect'.computed: {  
      emptyText() {
        if (this.options.length === 0) {
           return this.noDataText || this.t('el.select.noData');
        } 
        // ...}},// ...
} 
Copy the code

t(path)

This. T (‘ el.select.nodata ‘) calls the t method according to the passed path value el.select.nodata, and the options parameter is undefined. By default, no third-party plug-ins or custom methods are introduced. Find the corresponding copy directly from the default language (simplified Chinese) configuration.

If the value is “no data” and the options parameter is “undefined”, use the format method (template method defined by SRC /locale/format.js) to format the text.

format('No data'.undefined) = >'No data'
Copy the code

The components are displayed as follows: πŸ‘‡.

t(path, options)

In Pagination, this.t(‘el.pagination. Total ‘, {total: This.$parent-total}) pass the path value el.pagination. Total, with options set to {total: 1000}.

According to el.pagination. Total, the total value is {total}, which is a template string.

{
 el: {
   pagination: {
     goto: "前往".pagesize: "Bar/page".total: "Total {total} entries".pageClassifier: "Page",},// ...}}Copy the code

In this case, the value value is {total} and the options parameter is {total: 1000}. Use the format method to format the text.

format('Total {total} entries', {total: 1000}) = >'Total 1000 pieces'
Copy the code

Not all values are plain text, there are template strings. Introduce the format method defined by SRC /locale/format.js for string formatting operations.

The components are displayed as follows: πŸ‘‡.

0x03 Project internationalization setting

In the above section, we will discuss the implementation of the internal internationalization solution of the component in detail. This section describes how to configure multiple languages, introduce third-party plug-ins, and manually extend components.

A complete introduction

You can also pass an optional option object when using vue.use () to register components globally. Locale is used for language Settings and i18N custom i18N handling.

import Vue from 'vue'; 
import ElementUI from 'element-ui'; 
import lang from 'element-ui/lib/locale/lang/en';

import "element-ui/lib/theme-chalk/index.css"; 

Vue.use(ElementUI, {
  locale: lang,
  i18n: function(path, options) {
    // ...}});Copy the code

The install method in SRC /index.js provides locale.use(), locale.i18n(), and accepts opts, which is used to internationalize global Settings.

import locale from 'element-ui/src/locale'; 
// ...

const install = function(Vue, opts = {}) {
  locale.use(opts.locale);
  locale.i18n(opts.i18n); 
  // ...
}; 
Copy the code

According to the need to introduce

Components such as Button and Select can be registered in one of two ways: plugin registration vue.use () or component global registration Vue.component(); Introduce the locale method to set the language. Introduction of I18N method for processing method; .

import Vue from 'vue'; 
import { Button, Select, locale, i18n } from "element-ui";
import lang from 'element-ui/lib/locale/lang/en' 
// import locale from 'element-ui/lib/locale' 

import "element-ui/lib/theme-chalk/index.css";

// Set the language equivalent to locale.use()
locale(lang)

Locale.i18n () locale.i18n()
i18n(function(path, options) {
  // ...
});

// Import components
Vue.use(Button);
Vue.component(Select.name, Select) 

Copy the code

SRC /index.js export locale and i18n methods. Locale is the same as locale.use, i18n is the same as locale.i18n.

import locale from 'element-ui/src/locale'; 
// ...

const install = function(Vue, opts = {}) { 
  // ...
}; 

export default {
  locale: locale.use,
  i18n: locale.i18n,
  install,
  Button,
  Select,
  // ...
};
Copy the code

collocationvue-i18nuse

Projects can also introduce third-party plug-ins, such as Vue-i18n, the latest version of 8.x, which requires manual processing (Element compatible with 5.x).

import Vue from "vue"; 
import Element from "element-ui";
import VueI18n from "vue-i18n";
import enLocale from "element-ui/lib/locale/lang/en";
import zhLocale from "element-ui/lib/locale/lang/zh-CN"; 

Vue.use(VueI18n);

const messages = {
  en: {
    message: {
      hello: "hello world",},... enLocale,// Or use object.assign ({message: {hello: "hello world"}}}, enLocale)
  },
  zh: {
    message: {
      hello: "Hello world",},... zhLocale,// Or use object.assign ({message: {hello: "hello world "}}, zhLocale)}};// Create the VueI18n instance
const i18n = new VueI18n({
  locale: "zh".// Set the language
  messages, // Language translation content
});

// Register the Element custom i18N handler
Vue.use(Element, {
  i18n: (key, value) = > i18n.t(key, value),
});

new Vue({
  i18n,
  render: (h) = > h(App),
}).$mount("#app");

Copy the code

The test page

<template>
  <div id="app">
    <div>message.hello -- {{ $t("message.hello") }}</div>
    <div>el.select.noData -- {{ $t("el.select.noData") }}</div>
  </div>
</template>

<script>
export default {
  name: "App"};</script>
Copy the code

Set the language to zh and the output to:

Set language to EN, page output content:

0x04 Watch the column

This article has been included in the column πŸ‘‡, you can directly follow.