Ма Что Мэй? Что Н? Говоря об интернационализации в разработке веб-интерфейса

Java внешний интерфейс JavaScript Vue.js
Ма Что Мэй? Что Н? Говоря об интернационализации в разработке веб-интерфейса

I. Интернационализация, локализация, глобализация

Такой опыт есть у многих разработчиков.Несколько лет назад официальные сайты некоторых предприятий, учреждений и школ требовали: «Перевести и сделать англоязычную версию», а в результате часто приходилось вести отдельный набор англоязычных страниц.

В сегодняшней области разработки программного обеспечения, поскольку все больше и больше продуктов необходимо продавать на зарубежные рынки, простой и грубый подход прошлого неприменим; это требуетГибкость модификации программного обеспечения для адаптации к языку, региональным различиям и техническим потребностям целевого рынка..

В этой статье предпринята попытка дать краткое введение в связанные концепции, особенно их применение во внешнем веб-интерфейсе.

1.1 терминология

Когда дело доходит до интернационализации, часто используется несколько похожих терминов:

  • [глобализация]:internationalization, так как между первой и последней буквами 18 букв,Упоминается какi18n; относится к процессу отделения программного обеспечения от определенного языка и региона. Когда программное обеспечение переносится на разные языки и регионы, само программное обеспечение не требует внутренних инженерных изменений или доработок.
  • [локализация]:localization, по той же причинеУпоминается какl10n; относится к процессу перевода файлов для определенного региона и применения специальных макетов, добавления компонентов локальной специализации и т. д., чтобы позволить использовать программное обеспечение в этой конкретной языковой среде или регионе.
  • [Глобализация]:globalization, иногда используется для обозначения комбинации двух вышеуказанных; такжеУпоминается какg11n

Проще говоря:Международная постановка сцены, местное пение. Интернационализация означает, что продукт имеет «потенциал» для использования где угодно; локализация должна быть более подходящей для использования в «конкретном» месте, и добавляются дополнительные функции. Для продукта интернационализацию нужно сделать только один раз, а локализацию нужно сделать один раз для разных регионов. Они дополняют друг друга и вместе образуют систему, которая работает везде.

1.2 Характеристики интернационализации

Интернационализированное программное обеспечение имеет следующие характеристики:

  • Можно быстро локализовать
  • С локализованными данными одна и та же программа может работать в любой точке мира.
  • Текстовые элементы, такие как подсказки о состоянии, заголовки в интерфейсе и т. д., не являются жестко закодированными в программном обеспечении, а хранятся вне исходного кода и могут динамически изменяться.
  • Новые языки могут быть добавлены без перекомпиляции программного обеспечения
  • Информационное представление валюты, даты и т. Д., Чтобы адаптироваться к местоположению и языку пользователя.

1.3 Элементы, которые необходимо локализовать

В дополнение к валютам и датам, упомянутым выше, существует множество элементов, связанных с культурой, регионом и языком, например:

  • направление письма
  • звук
  • цвет
  • графика
  • значок
  • время
  • количество
  • мера
  • номер телефона
  • Почтение
  • заглавие
  • почтовый адрес
  • нумерация страниц
  • Метод сортировки
  • обработка ввода
  • диалект
  • правила
  • Мораль и привычки

II. Региональные настройки

Кромеi18n,l10n,g11nМы часто видим эти странные имена каждый деньlocaleЭто слово, значение которого обычноzh-CN,en-USЖдать.

ОдинlocaleОбъект — это специальный идентификатор, сочетающий в себе язык и локаль.

localeПредоставлено серией документов "BCP 47" "Internet Engineering Task Force" (IETF) (tools.I ETF.org/HTML/semi-47)определение.

Этораспространенная типичная формаОн состоит из двух частей, представляющих язык и регион соответственно.-соединение; регион также можно не указывать.

Например:

locale code обычное значение
en английский
en-US английский, на котором говорят в США
en-GB английский, на котором говорят в Великобритании
zh-CN Упрощенный китайский
zh-HK Традиционный китайский в Гонконге
zh-TW Традиционный китайский на Тайване
zh-SG Сингапурский упрощенный китайский
zh-MO Традиционный китайский в Макао
es-AR В Аргентине говорят на испанском
ar-001 Общий арабский
ar-AE Арабский язык, на котором говорят в ОАЭ

2.1 Зональная чувствительность

Вообще говоря, в соответствии с настройкой локали, поместитеhelloЕго можно перевести в «こんにちは» или «Hello» соответственно, но для чисел, дат, валют и т. д. требуются специальные форматы или вычисляются числа года и т. д., которые могут обрабатываться некоторыми специальными классами.

Код считается «чувствительным к локали», если его поведение зависит от локали.

Например, класс NumberFormat в Java чувствителен к локали; формат возвращаемого им числового значения зависит отlocale: может быть902 300(Франция) или902.300(Германия) или902,300(Америка).

Конечно, подобные классы сейчас присутствуют и в JS, о которых будет сказано далее.

должны знать о том,localeЭто всего лишь идентификатор, и конкретная работа по определению границ слов, форматированию и т. д. по-прежнему должна выполняться кодовыми модулями, чувствительными к региону.

2.2 Языковое кодирование

Первая половина локали представляет язык, обычно состоящий из 2 или 3 строчных букв, в соответствии сISO 639(ууууууууууууууууууууууууууууууууууууууууууууууууууууууууууууууууууууууууууууууууууууууууууууууууууууууууууууууууууууууу один.стандарт.

Например:

Language Code Description
de German
en English
fr French
ru Russian
ja Japanese
jv Javanese
ko Korean
zh Chinese

2.3 Код города

Вторая половина локали представляет регион, который определяетсяISO 3166(Woohoo. Машина выключена. Вице-Берлин.'s /diverse/doc…Стандартные 2 или 3 заглавные буквы илиUN M.49Стандартные три цифры. Эта часть не является обязательной.

Например:

A-2 Code A-3 Code Numeric Code Description
AU AUS 036 Australia
BR BRA 076 Brazil
CA CAN 124 Canada
CN CHN 156 China
DE DEU 276 Germany
FR FRA 250 France
IN IND 356 India
RU RUS 643 Russian Federation
US USA 840 United States

2.4 Более полные определения, которые используются реже

Эта часть контента редко используется, и вы можете понять это, вы можете обратиться к вики-ссылке в конце статьи.

Языковой тег состоит из одного или нескольких вложенных тегов с дефисом.-разделены. Вложенные теги могут состоять только из основных латинских букв или цифр.

В стандарте языковых тегов BCP 47 полными вложенными тегами являются:

подвкладка Это необходимо Это обычное дело объяснять
language да да см. 2.1
extended language нет нет До трех, каждая из которых состоит из трех букв. Не использовать на самом деле
script нет в общем 4 буквы, первая буква заглавная
region нет да см. 2.2
variant нет нет Чтобы еще больше различать диалекты, которые язык не может охватить; от 5 до 8 букв или 4 буквы, за которыми следует 1 цифра.
extension нет в общем Такие какuВ начале следует дефис и текст (), состоящий из 2–8 символов, который используется для представления Юникода, что повлияет на модули интернационализации с учетом региональных настроек, такие как NumberFormat.Подробнее см. пример ниже.
private-use нет нет кx-Частные языковые теги, начинающиеся с префикса

Самый простой пример выглядит следующим образом:

  • hi:Хинди
  • de-AT: немецкий язык, на котором говорят в Австрии.
  • zh-Hans-CN: упрощенный китайский, используемый в Китае.
  • zh-Hant-HK: Традиционный китайский язык, используемый в Гонконге, Китай.
  • zh-Hans: также включаетzh-CN,zh-SG(Сингапур) и другие регионы, использующие упрощенные китайские иероглифы.

Что касается части расширения, взгляните на этот пример интуитивно:

var date = new Date(1945,7,15);

function printDate(locale) {
    var dtf = new Intl.DateTimeFormat(
        locale,
        {era:"short"} //一个 options 对象,还有很多参数可设置
    );
    console.log( dtf.format(date) );
}

printDate("en"); //8 15, 1945 AD
printDate('ja-JP-u-ca-japanese'); //昭和20年8月15日
printDate('zh-Hant-u-ca-buddhist'); //佛曆2488年8月15日
printDate('zh-Hans-u-nu-thai-ca-japanese'); //昭和๒๐年๘月๑๕日
printDate("zh-Hans-u-nu-fullwide-ca-persian"); //波斯历1324年5月24日
printDate('zh-T' + 'W-u-ca-r' + 'oc'); //这个可以自己试一下~

Проще говоря, его формаu-Свободная комбинация сзадиnu-а такжеca-Два подраздела, указывающих, какому языку соответствует число и календарь. Доступные значения см. на странице Intl.DateTimeFormat в MDN.

#Зачем учить китайский#: Я не боюсь неба, я не боюсь земли, я просто боюсь, что южане скажут детский акцент

III.Кодировка символов

Сейчас, занимаясь веб-интерфейсом, с улучшением инструментов и фреймворков и популяризацией стандартов, «китайского искажения» стало меньше, но раньше такая ситуация часто встречалась на фронтенде и бэкенде, тогда необходимо чтобы понять кодировку символов.В некоторых случаях, когда требуется интернационализация, также должны быть сделаны соответствующие преобразования или объявления.

В начале проектирования компьютера не учитывались сценарии применения нескольких стран и разных языков. определитьASCIIкод, количество букв, цифр и других символов представлено 7-битным двоичным числом. Позже компьютеры стали популярны во всем мире.Чтобы адаптироваться к множеству символов, появились различные форматы кодирования.Например, формат кодирования, обычно используемый для китайских иероглифов,GB2312,GBK.

В результате возникает еще одна проблема, заключающаяся в том, что разные коды символов не могут быть распознаны друг от друга. Так оно и появилосьUnicodeкодирование. Он устанавливает единую и уникальную двоичную кодировку для каждого символа в каждом языке.

ноUnicodeЕсть и недостаток: для поддержки символов всех языков необходимо использовать больше цифр для представления, напримерASCIIДля представления английского символа требуется всего один байт, иUnicodeЕму нужны два байта. Очевидно, количество персонажей и более эффективность будет очень низким.

Чтобы решить эту проблему, были некоторые кодировки символов промежуточным форматом: например, общийUTF-8,так же какUTF-16,UTF-32Ждать.

IV. Интернационализация в Java

发黄的相片
古老的信
以及褪色的圣诞卡
年轻时为你写的...Java 代码里
已经有了成熟的 i18n 方案

Причина, по которой я хочу упомянуть «старый серверный язык» — интернационализацию в Java, заключается в том, что его решения — это решения интернационализации для более поздних инструментов/фреймворков, таких как jQuery, Vue.js и новый API интернационализации ECMAScript. влияние.

4.1 Файлы ресурсов

Java хранит текст на разных языках с суффиксом как.propertiesфайл в формате
<资源名>_<语言代码>_<国家/地区编码>.properties

где код языка и код страны являются необязательными;<资源名>.propertiesИменованный интернационализированный файл ресурсов является файлом ресурсов по умолчанию.

Обратите внимание, что здесь_подключений, и как указано в стандарте-немного отличается.

# MessagesBundle.properties
greetings = Hello.
farewell = Goodbye.
inquiry = How are you?
# MessagesBundle_zh_CN.properties
greetings = 嗨!
farewell = 再见!
inquiry = 吃了没?

Примечание. Если это китайский файл ресурсов, закодированный в ASCII, вам также необходимо использовать native2ascii для преобразования его в кодировку Unicode.

4.2 Выбор и загрузка языков

В Java используйтеjava.util.Localeлокаль выбора объекта; иjava.util.ResourceBoundleОн используется для загрузки локализованных файлов ресурсов.

import java.util.Locale;
import java.util.ResourceBundle;

public class I18NSample {

   static public void main(String[] args) {

      String language;
      String country;

      if (args.length != 2) {
          language = new String("en");
          country = new String("US");
      } else {
          language = new String(args[0]);
          country = new String(args[1]);
      }

      Locale currentLocale;
      ResourceBundle messages;

      currentLocale = new Locale(language, country);
      messages = ResourceBundle.getBundle("MessagesBundle",currentLocale);

      System.out.println(messages.getString("greetings"));
      System.out.println(messages.getString("inquiry"));
      System.out.println(messages.getString("farewell"));
      System.out.println("-----");
   }
}

Эта программа проста и понятна, выбирайте разные языковые пакеты по параметрам запуска и извлекайте из нее соответствующие поля.

javac I18NSample.java

java I18NSample
//Hello.
//How are you?
//Goodbye.

java I18NSample zh CN
//嗨!
//吃了没?
//再见!

4.3 Инструменты интернационализации

Несколько служебных классов формата интернационализации, зависящих от локали, также предоставляются в Java. Например:NumberFormat,DateFormat,MessageFormat

import java.util.Locale;
import java.util.ResourceBundle;
import java.util.Date;
import java.util.GregorianCalendar;
import java.text.NumberFormat;
import java.text.DateFormat;
import java.text.MessageFormat;

public class I18NSample2 {

   static public void main(String[] args) {

    double num = 123456.78;
    NumberFormat format = NumberFormat.getCurrencyInstance(Locale.SIMPLIFIED_CHINESE);
    System.out.format("%f 的本地化(%s)结果: %s\n", num, Locale.SIMPLIFIED_CHINESE, format.format(num));
    // 123456.780000 的本地化(zh_CN)结果: ¥123,456.78


    Date date = new Date();
    
    DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.JAPANESE);
    System.out.format("%s 的本地化(%s)结果: %s\n", date, Locale.JAPANESE, df.format(date));
    // Wed Oct 10 23:25:33 CST 2018 的本地化(ja)结果: 2018/10/10
    
    DateFormat df2 = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.SIMPLIFIED_CHINESE);
    System.out.format("%s 的本地化(%s)结果: %s\n", date, Locale.SIMPLIFIED_CHINESE, df2.format(date));
    // Wed Oct 10 23:25:33 CST 2018 的本地化(zh_CN)结果: 2018年10月10日

    
    Object[] params = {"Jack", new GregorianCalendar().getTime(), 8888};

    String pattern1 = "{0},你好!你于  {1} 消费  {2} 元。";
    String msg1 = MessageFormat.format(pattern1, params);
    System.out.println(msg1);
    // Jack,你好!你于  2018/10/10 下午11:25 消费  8,888 元。

    String pattern2 = "At {1,time,short} On {1,date,long},{0} paid {2,number, currency}.";
    MessageFormat mf = new MessageFormat(pattern2, Locale.US);
    String msg2 = mf.format(params);
    System.out.println(msg2);
    // At 11:25 PM On October 10, 2018,Jack paid $8,888.00.
   }
}

Григорианский календарь — это стандартное название григорианского календаря, календаря, заимствованного из западных обществ. Названа потому, что была провозглашена папой Григорием XIII в 1582 году. AD - это «эра григорианского календаря», также известная как «Xiyuan». -- Энциклопедия Байду

Прежде всего, объяснение именования класса GregorianCalendar приведено выше.Конечно, при написании международного кода также отлично слушать одноименный Григорианский Папский хор в Великобритании~

Во-вторых, в MessageFormat мы видим некоторые заполнители в строке шаблона сообщения. Правила примерно такие:

  1. Замените числа в фигурных скобках фактическим значением, переданным в
  2. Позиция числа может быть указана произвольно, и одно и то же число может появляться несколько раз.
  3. Полная форма фигурных скобок{ ArgumentIndex , FormatType , FormatStyle }, последние два являются необязательными
  4. FormatTypeМожет быть числом, датой, временем и т. д.
  5. FormatStyleМожет быть коротким, средним, длинным, полным, целым, валютным, процентным и т. д.

V. Интернационализация в jQuery

Как наиболее важный инструмент для продвижения веб-интерфейса в первые дни, jQuery является стандартным стандартом разработки эпохи.

При работе с требованиями интернационализации сам jQuery не содержит связанных модулей.jQuery.i18n.properties.

5.1 jQuery.i18n.propertiesспециальность

  • Как и в Java,jQuery.i18n.propertiesиспользовать.propertiesфайл для интернационализации кода JavaScript. Этот метод также обеспечивает удобство при совместном использовании файлов ресурсов между программами Java и программами внешнего интерфейса JavaScript.
  • Файл ресурсов называется<资源名>_<语言代码>-<国家/地区编码>.properties, где между языком и регионом принимается-соединение, цель состоит в том, чтобы быть совместимым с браузерами путемnavigator.languageилиjQuery.i18n.browserLang()полученное значение локали
  • В строках ресурсов можно использовать заполнители (например: привет = привет {0}! Сегодня {1}.)
  • Ключи в файлах ресурсов поддерживают пространства имен (например: com.company.msgs.hello = Hello!)
  • Поддержка значений через строки в файлах ресурсов
  • Поддержка использования ключа в файле ресурсов в качестве переменной (или функции) JavaScript или карты.

5.2 Основное использование

jQuery.i18n.properties({ 
   name:'strings',// 资源文件名称
   path:'bundle/',// 资源文件所在目录路径
   mode:'both',// 模式:变量或 Map 
   language:'pt_PT',// 对应的语言
   cache:false, //浏览器是否对资源文件进行缓存
   encoding: 'UTF-8', //编码。默认为 UTF-8
   callback: function() {// 回调方法
   } 
});

В обратном вызове обратного вызова вы можете позвонить·jQuery.i18n.prop(key)метод. Этот метод использует значение в файле ресурсов в качестве карты, где ключ относится к ключу в файле ресурсов. Когда значение, указанное ключом, содержитЗаполнитель, вы можете использоватьjQuery.i18n.prop(key,var1,var2 … ), где var1,var2 … замените заполнители по очереди.

VI. Интернационализация в Vue.js

С появлением инструментов разработки индексов Angular, React, Vue.js эти тройки также открыли новую эру разделения клиентской и серверной части, и большая часть логики разработки была перенесена из серверной части во фронтальную. end, и соответствующие требования интернационализации также более распространены, а их требования к гибкости и простоте использования выше.

Здесь мы возьмем Vue.js в качестве примера для анализа его общих решений i18n.

vue-i18n (kazupon.github.io/vue-i18n/) — широко используемый плагин интернационализации Vue.js, его основные функции включают в себя:

  • Локализация в различных форматах
  • Поддерживает языковые правила, такие как множественное число (Pluralization)
  • Локализация даты и времени
  • Локализация номера
  • локализация на основе компонентов
  • Компонентная интерполяция
  • Резервная локализация

6.1 Основное использование

<div id="app">
  <p>{{ $t("message.hello") }}</p>
</div>

import Vue from 'vue'
import VueI18n from 'vue-i18n'

// 注册插件
Vue.use(VueI18n)

// 多语言信息
// 一般可以单独模块化,放到 i18n.js 等文件中
const messages = {
  en: {
    message: {
      hello: 'hello world'
    }
  },
  ja: {
    message: {
      hello: 'こんにちは、世界'
    }
  }
}

// 传入一个 options,创建一个 VueI18n 实例
const i18n = new VueI18n({
  locale: 'ja', // 区域设置
  messages, 
})

// 在 Vue 的实例化选项中传入 i18n
new Vue({ i18n }).$mount('#app')

输出:

<p>こんにちは、世界</p>

Видно, что Vue.js больше не зависит от.propertiesФайлы ресурсов, но используйте собственное объектное или модульное решение JS.

6.2 Грамматика многоязычных ресурсов

Помимо простых пар ключ-значение, Vue.js поддерживает несколько гибких синтаксисов:

{
  "en": {  // 英语
      "key1": "this is message1", // 基础的键值对
      "nested": { // 嵌套的
        "message1": "this is nested message1"
      },
      "errors": [ // 数组,里面可以放各种值
        "this is 0 error code message",
        {"internal1": "this is internal 1 error message"},
        ["this is nested array error 1"]
      ],
      
      //常用词语可以用来拼接
      "the_world": 'the world',
      "dio": 'DIO:',
      "linked": '@:message.dio @:message.the_world !!!!'
  },
  "ja": { // 日语
    // ...
  }
}

<p>{{ $t('key1') }}</p>
<p>{{ $t('nested.message1') }}</p>
<p>{{ $t('errors[0]') }}</p>
<p>{{ $t('errors[1].internal1') }}</p>
<p>{{ $t('errors[2][0]') }}</p>

<p>{{ $t('message.linked') }}</p>

6.3 Заполнители

Традиционная форма-заполнитель, именуемая здесь «Форматирование списка»:

<p>{{ $t('message.hello', ['你好','小明']) }}</p>

const messages = {
  en: {
    message: {
      hello: '{0} world, I am {1}'
    }
  },
  zh: {
    message: {
      hello: '我是{1}, 世界,{0}!我是{1}!'
    }
  }
}

const i18n = new VueI18n({
  locale: 'zh',
  messages
})

输出:

<p>我是小明, 世界,你好!我是小明!</p>

Также поддерживается форма входящих ключей-значений, называемая «Именованное форматирование»:

<p>{{ $t('message.goodbye', {day: "明天"}) }}</p>

const messages = {
  zh: {
    message: {
      hello: '我是{1}, 世界,{0}!我是{1}!',
      goodbye: '再见!{day}见!'
    }
  }
}

输出:

<p>再见!明天见!</p>

6.4 Локализация даты и времени

<p>{{ $d(new Date(1945,7,15)) }}</p>
<p>{{ $d(new Date(1945,7,15), 'config2', 'ja-JP') }}</p>

const dateTimeFormats = {
  'en-US': {
  },
  'ja-JP': {
    config1: {
      year: 'numeric', month: 'short', day: 'numeric'
    },
    config2: {
      year: 'numeric', month: 'short', day: 'numeric',
      weekday: 'short', hour: 'numeric', minute: 'numeric', hour12: true,
      era: 'short'
    }
  }
}

const messages = {
  en: {
  },
  ja: {
  }
}

const i18n = new VueI18n({
  locale: 'ja', // 区域设置
  messages, 
  dateTimeFormats // 多传入一个日期时间格式
})

输出:

<p>1945/8/15</p>
<p>西暦1945年8月15日(水) 午前0:00</p>

Синтаксис показан в коде, и можно просмотреть конкретные элементы конфигурации.ООО, ООО .ec Код -international.org/ec Код -402 / 2 ...

6.5 Номерка Локализация

<p>{{ $n(100, 'currency') }}</p>
<p>{{ $n(100, 'currency', 'ja-JP') }}</p>

const numberFormats = {
   'en-US': {
     currency: {
       style: 'currency', currency: 'USD'
     }
   },
   'ja-JP': {
     currency: {
       style: 'currency', currency: 'JPY', currencyDisplay: 'symbol'
     }
   }
 }

const messages = {
  en: {
  },
  ja: {
  }
}

const i18n = new VueI18n({
  locale: 'ja', // 区域设置
  messages, 
  numberFormats // 多传入一个数字格式
})

输出:

<p>$100.00</p>
<p>¥100</p>

Синтаксис также не сложен для понимания, а конкретные элементы конфигурации можно посмотретьdeveloper.Mozilla.org/en-US/docs/…

6.6 Компонентный i18n

В дополнение к передаче настроек интернационализации в качестве параметров конструктора в корневом экземпляре Vue, i18n также может быть установлен в одном компоненте Vue, его область действия ограничена самим компонентом, а поля, которые повторяются при глобальной интернационализации, будут отображаться первыми. .

<div id="app">
  <p>{{ $t("message.hello") }}</p>
  <component1></component1>
</div>

// Vue 根实例和全局的`i18n`
const i18n = new VueI18n({
  locale: 'ja',
  messages: {
    en: {
      message: {
        hello: 'hello world',
        greeting: 'good morning'
      }
    },
    ja: {
      message: {
        hello: 'こんにちは、世界',
        greeting: 'おはようございます'
      }
    }
  }
})

// 定义组件
const Component1 = {
  template: `
    <div class="container">
     <p>Component1 locale messages: {{ $t("message.hello") }}</p>
     <p>Fallback global locale messages: {{ $t("message.greeting") }}</p>
   </div>`,
  i18n: { // 局部的 `i18n` 
    messages: {
      en: { message: { hello: 'hello component1' } },
      ja: { message: { hello: 'こんにちは、component1' } }
    }
  }
}

new Vue({
  i18n,
  components: {
    Component1
  }
}).$mount('#app')

输出:

<div id="app">
  <p>こんにちは、世界</p>
  <div class="container">
    <p>Component1 locale messages: こんにちは、component1</p>
    <p>Fallback global locale messages: おはようございます</p>
  </div>
</div>

6.7 Интерполяция компонентов

иногда есть操作失败,请参考<a href="{1}">{0}</a>页面или总金额:<em>{0}</em>元Такая локализованная информация.

Интуитивно понятный метод может состоять в том, чтобы объединить его в несколько абзацев, избегая html-части или используяv-html="$t('xxx')"Внесите его целиком.

Но две вышеупомянутые меры либо громоздки и не элегантны, либо принесут XSS-риски.

В vue-i18n интерполяция компонентов может лучше решать такие проблемы:

<div id="app">
  
  <i18n path="info" tag="p">
    <span place="limit"> <!--注意 place 属性的应用-->
      {{ changeLimit }}</span>
    <a place="action" 
       :href="changeUrl">
      {{ $t('change') }}</a>
  </i18n>
  
</div>

const messages = {
  en: {
    info: 'You can {action} until {limit} minutes from departure.',
    change: 'change your flight'
  }
}

const i18n = new VueI18n({
  locale: 'en',
  messages, 
})

new Vue({
  i18n,
  data: {
    changeUrl: '/change',
    changeLimit: 15
  }
}).$mount('#app')

输出:

<div id="app">
    <p>
        You can 
        <a place="action" href="/change">change your flight</a> 
        until 
        <span place="limit">15</span> 
        minutes from departure.
    </p>
</div>

6.8 i18next

Еще один отличный плагин интернационализации Vue.js —i18next (GitHub.com/i18next/i18…), эта статья не будет расширять введение

VII. Новый API интернационализации JS

В конце 2012 года ECMA International выпустила первую версию стандарта Standard ECMA-402, более известного как API интернационализации ECMAScript. Этот стандарт дополняет давно назревшую поддержку методов локализации в ECMAScript. Практически все современные браузеры уже поддерживают этот API.

7.1 Intlглобальный объект

IntlObject — это пространство имен API интернационализации ECMAScript, которое обеспечивает точное сравнение строк, форматирование чисел, а также форматирование даты и времени.Collator,NumberFormatа такжеDateTimeFormatКонструктор объектаIntlсвойства объекта.

  • Intl.CollatorКонструктор для сортировщиков, объектов, которые позволяют сравнивать строки с учетом языка.
  • Intl.DateTimeFormatКонструктор для объектов, которые позволяют форматировать дату и время с учетом языка.
  • Intl.NumberFormatКонструктор для объектов, которые позволяют форматировать числа с учетом языка.
  • Intl.PluralRulesКонструктор для объектов, которые позволяют использовать несколько конфиденциальных форматов и правил для нескольких языков.

Как мы уже видели в 2.3DateTimeFormatНапример, все эти конструкторы используют один и тот же шаблон для определения локали и определения используемого языкового формата: все они принимают локали и параметры в качестве аргументов.

optionsПараметр должен быть объектом, значения свойств которого варьируются в конструкторах и методах. еслиoptionsАргумент не указан или естьundefined, все значения свойств используют значения по умолчанию.

Давайте рассмотрим несколько простых примеров:

var number = 123456.789;

// 德语使用逗号作为小数点,使用.作为千位分隔符
console.log(new Intl.NumberFormat('de-DE').format(number));
// → 123.456,789

// 通过编号系统中的nu扩展键请求, 例如中文十进制数字
console.log(new Intl.NumberFormat('zh-Hans-CN-u-nu-hanidec').format(number));
// → 一二三,四五六.七八九


// 德语中, ä 使用 a 的排序
console.log(new Intl.Collator('de').compare('ä', 'z'));
// → -1

// 瑞典语中, ä 在 z 的后面
console.log(new Intl.Collator('sv').compare('ä', 'z'));
// → 1


var date = new Date(Date.UTC(2012, 11, 20, 3, 0, 0));

// 使用24小时制
options = {
  year: 'numeric', month: 'numeric', day: 'numeric',
  hour: 'numeric', minute: 'numeric', second: 'numeric',
  hour12: false
};
console.log(date.toLocaleString('en-US', options));
// → "12/19/2012, 19:00:00"

7.2 intl.js polyfill

Для некоторых старых браузеров без собственного Intl API вы можете использоватьGitHub.com/Энди глупо зарабатывает…Поддерживается большинство функций.

7.3 Приложение: Метод получения лунной даты

До появления нового API вычисление лунного календаря было сложным и имело ограничение по максимальному году, использование нового API может очень хорошо решить эту проблему.

Следующий метод улучшен изJS fiddle.net/Дерек л/мг XK…

function getLunarDate(date) {
  const TIAN_GAN = ["甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"];
  const DI_ZHI = ["子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"];
  const SHI = ["初", "十", "廿", "三"];
  const YUE = ["", "十"];
  const GE = ["一", "二", "三", "四", "五", "六", "七", "八", "九", "十"];
  
  const locale = "zh-TW-u-ca-chinese";
  const fmt = (key, d=null)=>{
  	return Intl.DateTimeFormat(locale,{[key]:"numeric"}).format(d||date).match(/\d+/)[0];
  };
  const isLeapMonth = (d)=>{
  	let _date = new Date(date);
    _date.setDate(-d);
    return fmt("month", _date) === m;
  };
  
  let y = fmt("year");
  let m = fmt("month");
  let d = fmt("day");

  isL = isLeapMonth(d);

  y = TIAN_GAN[(y - 1) % 10]
  	+ DI_ZHI[(y - 1) % 12];
  m = (YUE[(m - 1) / 10 | 0]
  	+ GE[(m - 1) % 10]).replace(/^一$/, "正");
  d = (SHI[(d) / 10 | 0]
  	+ GE[(d - 1) % 10]).replace(/^十十$/, "初十").replace(/^廿十$/, "二十");

  return y + "年" + (isL ? "閏" : "") + m + "月" + d;
}

var date = new Date(1945,7,15);
var lunar = getLunarDate(date);
console.log(lunar); //乙酉年七月初八

VIII. Ссылки

-- End --