SkateJS — это библиотека для создания веб-компонентов с реактивными возможностями, поддержкой JSX и удобной системой жизненного цикла. Одним из часто встречающихся требований в современных приложениях является поддержка нескольких языков с возможностью динамической смены локали. SkateJS предоставляет инструменты, позволяющие реализовать такой функционал на уровне компонентов без потери производительности и чистоты кода.
Для динамической смены языка необходимо централизованно хранить текущее значение локали. В SkateJS рекомендуется использовать реактивные свойства компонента. Пример декларации:
import { Component, h, prop } from 'skatejs';
class I18nComponent extends Component {
static props = {
locale: prop.string({
attribute: true,
default: 'en',
reflect: true
})
};
render() {
return (
<div>{this.translate('greeting')}</div>
);
}
translate(key) {
return I18nComponent.messages[this.locale][key] || key;
}
}
I18nComponent.messages = {
en: {
greeting: 'Hello!'
},
ru: {
greeting: 'Привет!'
},
es: {
greeting: '¡Hola!'
}
};
customElements.define('i18n-component', I18nComponent);
Ключевые моменты:
prop.string() создаёт реактивное свойство
locale, которое автоматически обновляет компонент при
изменении.messages позволяет хранить
переводы в структуре { locale: { key: value } }.translate обращается к текущей локали и
возвращает соответствующий текст, или ключ, если перевод
отсутствует.SkateJS автоматически перерисовывает компонент при изменении реактивного свойства. Динамическая смена локали осуществляется простым присвоением нового значения:
const component = document.querySelector('i18n-component');
// Смена языка на русский
component.locale = 'ru';
// Смена языка на испанский
component.locale = 'es';
При этом render() вызывается автоматически, и
отображаемый текст обновляется без необходимости ручного
вмешательства.
Если приложение содержит вложенные компоненты, которые также должны реагировать на смену языка, рекомендуется использовать общий объект состояния локали или события CustomEvent.
export const LocaleState = {
current: 'en',
listeners: new Set(),
set(locale) {
this.current = locale;
this.listeners.forEach(cb => cb(locale));
},
subscribe(cb) {
this.listeners.add(cb);
return () => this.listeners.delete(cb);
}
};
Компонент подписывается на изменения:
class NestedComponent extends Component {
connectedCallback() {
super.connectedCallback();
this.unsubscribe = LocaleState.subscribe(locale => {
this.locale = locale;
});
}
disconnectedCallback() {
super.disconnectedCallback();
this.unsubscribe();
}
static props = {
locale: prop.string()
};
render() {
return <span>{I18nComponent.messages[this.locale].greeting}</span>;
}
}
Для крупных приложений рационально использовать ленивую загрузку словарей, чтобы не загружать все переводы сразу. В SkateJS это удобно реализуется через динамический импорт:
async function loadMessages(locale) {
const messagesModule = await import(`./locales/${locale}.js`);
I18nComponent.messages[locale] = messagesModule.default;
}
После загрузки словаря можно обновить локаль:
loadMessages('fr').then(() => {
component.locale = 'fr';
});
Преимущества:
Для полного i18n-решения необходимо учитывать не только текстовые строки, но и форматы чисел, дат и валют. SkateJS не ограничивает разработчика в использовании стандартного API Jav * aScript:
function formatDate(date, locale) {
return new Intl.DateTimeFormat(locale, { dateStyle: 'long' }).format(date);
}
function formatNumber(value, locale) {
return new Intl.NumberFormat(locale).format(value);
}
Пример использования в компоненте:
render() {
const today = new Date();
return (
<div>
<p>{this.translate('greeting')}</p>
<p>{formatDate(today, this.locale)}</p>
<p>{formatNumber(1234567.89, this.locale)}</p>
</div>
);
}
SkateJS поддерживает JSX и слоты, что позволяет внедрять локализованный контент глубоко в структуру компонента:
render() {
return (
<section>
<h1>{this.translate('title')}</h1>
<slot name="description"></slot>
</section>
);
}
Слоты могут быть динамически обновлены при смене локали, если
передавать в них компоненты с реактивным свойством
locale.
prop) обеспечивают автоматическое
обновление компонента при смене языка.Intl покрывают локализацию чисел, валют
и дат.Такой подход позволяет строить масштабируемые веб-приложения на SkateJS с полной поддержкой мультиязычности, сохраняя реактивность и простоту управления локалью.