[Что вам следует знать] Общее решение для интернационализации внешнего интерфейса

JavaScript

skFeTeam Автор этой статьи: Ван Фен

международный фон

Фронтенд-технологии меняются с каждым днем, и существует множество технологических стеков. Что касается интерфейсных фреймворков,React, Vue, Angularподожди, добавьwebpack, gulpИ т. д. создавайте инструменты для ежедневной работы по разработке. При этом в повседневной работе среди разных проектов использование стека технологий будет разным. Когда вам нужно со стороны международного проекта трансформации из-за различий в стеке технологий, вам нужно найти и использовать стек технологий, который соответствует текущему проекту интернационализации подключаемых инструментов. Например:

  • vue + vue-i18n
  • angular + angular-translate
  • react + react-intl
  • jquery + jquery.i18n.property

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

Чтобы снизить стоимость изучения подключаемых модулей интернационализации, связанных с различными технологическими стеками и ямами интернационализации, которые могут возникнуть в процессе разработки, после попытки проанализировать основные проблемы, с которыми сталкивается интерфейсная интернационализация и связанные с ними решения, я думаю Можно использовать более общее техническое решение для завершения работы по интернационализации.

Цель этой статьи

Переведите информацию, отображаемую на странице, на разные языки, вы можете разработать несколько версий для разных языков, а затем отображать разные страницы в соответствии с языком, выбранным пользователем. Но это требует больших затрат, а также очень хлопотно в обслуживании.Если проблема в одном месте, надо модифицировать все версии. Первоначальная цель этой статьи — найти более общее решение интернационализации.

Вопросы интернационализации, которые следует учитывать

1. Копирайтинговый перевод

  • Преобразование статической копии (копия статического шаблона внешнего интерфейса)

    Используйте подключаемый модуль интернационализации i18n, чтобы соответствовать переназначению словаря (оценочная рабочая нагрузка довольно велика)

  • Перевод динамической копии (serverдинамические данные, отправленные клиентом)

2. Стиль

  • Путаница в стиле из-за разной длины языка

    Например: когда elementui переключается между китайским и английским языками, строка и заголовок таблицы смещаются.

    表行、表头错位问题的解决方法:
     <el-table-column 
    	prop="a" 
    	:label="$t('b.c')"
    	show-overflow-tooltip="true"
     	:width="($t('b.c')).length*18"
      >
     
    其中:
    1. show-overflow-tooltip="true"表示内容超出宽度后省略号表示
    2. a表示绑定的数据
    3. b.c表示国际化zh.js,en.js中对应显示的表头名称
    
  • проблема со стилем h5, длина китайского и английского разная, раскладка беспорядочная

    Решение:

    Добавьте переменную, которая может динамически переключать класс в div html верхнего уровня, чтобы изменить имя класса родителя проекта, и переключать стиль css при переключении языка. Следующие каштаны:

    HTML-раздел
    <template>
      <div :class="langCss">
      </div>
    </template>
    
    Js часть
    在data中定义保存class的变量
    data () {
        return {
          langCss:window.localStorage.getItem('lang')||'zh',
          //先去取localStorage里保存的语言,如果没有,那么就默认中文
          //这么做的意义是为了用户在刷新页面的时候样式不丢失。
     }
    

    Затем добавьте новую строку сразу после нашей функции switchlLang, чтобы переключать классы при переключении языков.

    switchLang(lang)  {
        this.$i18n.locale = lang 
        localStorage.setItem('lang',lang);
        this.langCss=lang;//新添加的,以便切换父级class
    }
    
    CSS-раздел

    Установите нужный стиль в теге стиля.В качестве примера я возьму изменение цвета текста.

    .en button {
      color: steelblue;
    }
    .zh button {
      color: #666;
    }
    .ja button {
      color: seagreen;
    }
    

    Краткое изложение решений путаницы в стилях:

    1. При написании страницы старайтесь не писать ширину и высоту упаковочного контейнера 2. Языковые переменные записываются на самом внешнем уровне, который обертывает другие классы.

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

    4. Есть еще один метод (то есть скрытие переполнения): переполнение: скрыто, пробел: теперь, переполнение текста: многоточие, переполнение текста: многоточие;

    5, h5 лучше использовать адаптивную верстку

  • Замена картинок

3. Проблемы с часовым поясом

Если взять Таиланд в качестве примера, соответствующая база данных развернута в Таиланде. Если вы создаете часть данных в Китае и вставляете ее в базу данных Таиланда, выберите время создания данных через контроль времени, и время, полученное в это время, будет получено из браузера как время в китайском часовом поясе. Это время необходимо передать на внутренний сервер и сохранить в базе данных, но время сервера — это время часового пояса Таиланда. Китай - это Восточный восьмой округ, а Таиланд - Восточный седьмой округ, разница в один час. Это приводит к двум проблемам:

a、创建数据:在前端选的8:00,落到数据库中就会变为7:00

b、数据查询时的错觉:在前端选择查询8点到9点创建的数据,到后端经过转换会变为查找7:00到8点的消息,返回的数据又会带有相应的时区,导致,数据的一种假象。以为查的是8点到9点创建的数据,而实际看到的是7:00到8点的消息。

Отслеживание проблем показало, что время, переданное из внешнего интерфейса, будет преобразовано во время соответствующего часового пояса после преобразования формата времени Java.

Проблема с часовым поясом решена:

1. Для такого рода проблем часовой пояс базы данных обычно устанавливается на время UTC. Данные, передаваемые внешним интерфейсом, добавляют поле часового пояса, чтобы определить, какой это часовой пояс. Серверная часть преобразует это время во время UTC. часовой пояс и передает его в базу данных.В то же время время, возвращаемое базой данных, передается снова.Пропускайте часовой пояс, требуемый внешним интерфейсом, что позволит эффективно избежать проблем с часовым поясом.

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

3. Еще один простой подход: удалить формат времени из всего внешнего интерфейса и взаимодействовать с внутренним интерфейсом в виде строки. Бэкенд конвертирует время в строку и отправляет на фронтенд.Время фронтенда тоже обрабатывается как строка и отсылается на бэкенд. , какое время в библиотеке)

4. обслуживание таблицы сопоставления языков карты

5. Услуги третьих лиц

  • SDK

6. Локализация

  • Валютная единица

    Используйте арабские цифры, денежные единицы используют ฿, чтобы добавить обработку функции инструмента форматирования валюты.

  • Формат времени

8. Проблема перевода длинной копии и переменных

  • перевод этого предложения我被用户 xxx 拉进一个群聊когда. Английский переводI was dragged into a group chat by user xxx. Место, где появляется xxx, несовместимо. В настоящее время мы не можем просто установить его напрямую.en.jsа такжеzh,jsдля преобразования.

  • Мы можем заменить эту переменную символом здесь, а затем инкапсулировать функцию, чтобы она соответствовала переменной для замены我被用户 %s 拉进一个群聊,I was dragged into a group chat by user %s

  • код функции пакета

    function tplParse(tpl, params) {
        let counter = 0;
        if (params && params.length > 0) {
        let match;
        while(match = tpl.match(/%s/)) {
        tpl = tpl.slice(0, match.index) + params[counter] +tpl.slice(match.index + 2);
        counter ++;
    	}
      }
      return tpl;
    }
    
  • Первый параметр — это заменяемый текст, а второй параметр — заменяемая переменная.

9. Пройденные данные не могут вступить в силу при переключении языков

  • При переключении языков мы обнаружим, чтоrouterизindex.jsЯзык в не может быть переключен. Это связано с тем, что данные создаются в одно время, и обычный способ их записи заключается в получении этих интернационализированных значений при инициализации данных и не может реагировать на изменения. Решение, полученное путем обращения к копии, заключается в том, что данные, которые необходимо пройти, пересчитываются путем вычисления и возврата. Поскольку мест много, это решение слишком сложно для реализации. Временное решение — обновлять страницу при переключении языков.

решение

В ежедневном процессе разработки наиболее распространенными сценариями, требующими интернационализации, являются:语言翻译,样式,map表维护а также打包方案. Далее будет объяснено общее решение для интернационализации на основе этих фрагментов контента и в сочетании с ежедневным процессом разработки.

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

  1. используемые инструменты сборки
    • webpack
    • gulp
    • ...

На основе этих инструментов сборки используйте:

  • Vue
  • Angular
  • React
  • ...
  • не используя никакихframework
  1. Инструменты сборки не используются
    • использовалjqueryилиzeptoи т.д. библиотека
    • Роднойjs

общий

Общие этапы метода интернационализации внешнего интерфейса следующие: (принцип)

  • Определить конфигурацию интернационализации

  • Чтение конфигурации в соответствии с окружением

  • Отобразить конфигурацию на странице

Развернуть сказал:

  1. Определите конфигурацию интернационализации: Существует множество способов их определения, большинство из которых сохраняются отдельно в виде файлов, таких как json, js, properties и т. д. И сохраните информацию о конфигурации в виде пар ключ-значение для резервного копирования.
  2. Прочитайте конфигурацию в соответствии с окружением: Так называемая среда — это просто знак, выбранный пользователем, в следующем виде:тип хеша: #сп; #ан; #настип поиска: ?lan=cn; ?lan=en; ?lan=usURL/метатип: 163.com/cai/; 163.com/enкэшированный: форма кеша в основном cookie, по умолчанию cn, и кеш будет обновлен после того, как пользователь сбросит его.
  3. Отобразите конфигурацию на странице: Используйте сторонние плагины или напишите свои собственные плагины для сопоставления информации о конфигурации со страницами, Его можно использовать, нет плагинов для обычных, таких как juery.i18n.js или плагинов для интернационализации react и angular. Основной принцип плагина заключается в сопоставлении и замене значения ключа словарного запроса.

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

необычный тип

Шаги необычного метода следующие: (принцип)

  • Распространите конфигурацию интернационализации в различных файлах, таких как:<a class='i18n'>登录|登入|Sign in|サインイン|로그인</a>

  • Определите метку интернационализации в соответствии со средой: сп: 0, тв: 1, ан: 2, мп: 3, кр: 4

  • Отображение информации на основе тегов интернационализации Глобальный поиск элементов с class=i18n и сохранение соответствующей информации

крайний

  • использовать плагин гугл переводчик

Общее решение [di18n-translate]

Комбинируя различные инструменты построения, среды разработки и библиотеки классов, кажется, что можно найти более общее решение интернационализации для различных сред разработки.

Общая идея этой схемы такова: выполнить ее через строительный инструмент样式, 图片替换, class属性Для работы по замене не будет слишком много имен переменных из-за интернационализации в бизнес-коде, и для ее завершения используется общая функция перевода.静态文案а также动态文案работа перевода без использования соответствующих плагинов интернационализации, предоставляемых различными фреймворками. Проще говоря:

  • в зависимости от того, что вы используете构建工具+ универсальный翻译函数завершить интерфейсную интернационализацию

Во-первых, это универсальноефункция языкового перевода: di18n-translate. Функция, которую он обеспечивает, — это перевод статической и динамической копии, независимой от сред разработки и инструментов сборки.

  npm install di18n-translate

В настоящее время вам нужно только соответствующим образом интегрировать эту общую функцию перевода в вашу среду разработки.

Далее будут описаны соответствующие решения в сочетании с конкретными различными сценариями:

1. ИспользуйтеMVVMкаркас класса

использовалMVVMКатегорияframework, вы можете использоватьframeworkпомочь тебе закончитьviewработает рендеринг слоя, то вы можете легко управлять им через код в кодеclassконтент и замена изображений работают в разных локалях.

Напримерvue, Пример (1):

app.vue文件:
  <template>
    <p class="desc"
      :class="locale"   // locale这个变量去控制class的内容
      :style="{backgroundImage: 'url(' + bgImg + ')'}"  // bgImg去控制背景图片的路径
    ></p>
    <img :src="imgSrc"> // imgSrc去控制图片路径
    <p>{{title}}</p>
  </template>

  <script>
    export default {
      name: 'page',
      data () {
        return {
          locale: LOCALE,
          imgSrc: require(`./images/${LOCALE}/${LOCALE}.png`),,
          bgImg: require(`./images/${LOCALE}/${LOCALE}.png`),,
          title: this.di18n.$t('你好')
        }
      }
    }
  </script>

В настоящее время вы можете добавить функцию перевода, чтобы соответствовать большинству сценариев интернационализации.main.jsдобавить функцию перевода вdi18n-translateЦитата:

main.js文件:

import Vue from 'vue'

window.LOCALE = 'en'
const DI18n = require('di18n-translate')
const di18n = new DI18n({
    locale: LOCALE,       // 语言环境
    isReplace: false,   // 是否进行替换(适用于没有使用任何构建工具开发流程)
    messages: {         // 语言映射表
      en: {
        你好: 'Hello, {person}'
      },
      zh: {
        你好: '你好, {person}'
      }
    }
  })

Vue.prototype.d18n = di18n

использоватьmvvm frameworkДля интернационализации вышеописанный метод должен быть более подходящим, в основном с использованиемframeworkпомочь тебе закончитьviewРабота по рендерингу слоев, а затем введение функции перевода для завершения работы по динамическому копирайтингу.

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

2. Частичные страницы отображения

htmlдокумент:

  <div class="wrapper" i18n-class="${locale}">
    <img i18n-img="/images/${locale}/test.png">
    <input i18n-placeholder="你好">
    <p i18n-content="你好"></p>
  </div>

Время выполнения:

  <script src="[PATH]/di18-translate/index.js"></script>
  <script>
    const LOCALE = 'en'
    const di18n = new DI18n({
      locale: LOCALE,
      isReplace: true,   // 开启运行时
      messages: {
        en: {
          你好: 'Hello'
        },
        zh: {
          你好: '你好'
        }
      }
    })
  </script>

наконецhtmlпреобразуется в:

  <div class="wrapper en">
    <img src="/images/en/test.png">
    <input placeholder="Hello">
    <p>Hello</p>
  </div>

3. Используйте инструменты сборки

Далее поговорим о проектах, которые разрабатываются модульно с помощью инструментов сборки, эти проекты могут быть перечислены на последней странице.DOMна всем протяженииjsдля динамической вставки на страницу.htmlдокумент:

  <div class="wrapper ${locale}">
    <img src="/images/${locale}/test.png">
    <p>$t('你好')</p>
  </div>

jsдокумент:

  let tpl = require('./index.html')
  let wrapper = document.querySelector('.content')
  
  // di18n.$html方法即对你所加载的html字符串进行replace,最后相对应的语言版本
  wrapper.innerHTML = di18n.$html(tpl)

последняя страница вставленаDOMдля:

  <div class="wrapper en">
    <img src="/images/en/test.png">
    <p>Hello</p>
  </div>

В настоящее время динамический перевод использует импортированныйdi18nВверх$tметод

  di18n.$t('你好')

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

Принцип реализации интернационализации

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

Фреймворки, перечисленные в начале статьи, имеют общую черту, то есть все они имеют что-то похожее на языковой пакет.

zh.json
en.json
jp.json
...

Это также легко понять.Он разделяет различные языки для легкого управления и обслуживания.

Для простоты тестирования мы убрали процесс запроса и записали его прямо вjsonВнутри объекта следующим образом

intl.js

var intl = 
{
    "zh": {
        "title": "测试",
        "content": "这是一个测试"
    },
    "cn": {
        "title": "test",
        "content": "this is a test"
    }
}

Возможно, написать какие-то такие языки конфигурации, а затем каким-то образом установить соответствующие поля в соответствующие позиции.

Ниже псевдокод

<h2 id="title">测试</h2>
<p id="content">这是一个测试</p>
var lang = getGlobalVar('LOCALE')||'zh';//获取语言
var local = intl['lang'];

$title.innerHTML = local['title'];
$content.innerHTML = local['content'];

Выше приведена простая идея реализации.Если это простая статическая страница, то ее можно использовать и таким образом, и нет необходимости внедрять какие-то сторонние библиотеки, а потом жрать егоapi.

резюме:

Интернационализация выходит далеко за рамки простого перевода статического текста на странице, но также включает услуги локализации (время, валюта и т. д.). Я надеюсь, что благодаря этой статье у вас будет определенное понимание интернационализации внешнего интерфейса.

Если вы хотите узнать больше о публикациях skFeTeam, вы можете нажатьздесь, спасибо~