Slim.js — это легковесная библиотека для создания веб-компонентов с декларативным синтаксисом, которая позволяет управлять состоянием и жизненным циклом компонентов. Она прекрасно сочетается с Vue.js, обеспечивая возможность внедрять Slim-компоненты внутрь Vue-приложений и наоборот, расширяя возможности модульного и реактивного программирования.
Для использования Slim.js внутри Vue-проекта достаточно подключить библиотеку через npm:
npm install @slim-js/core
Или подключить через CDN в index.html проекта:
После этого можно регистрировать Slim-компоненты как кастомные элементы и использовать их внутри Vue-шаблонов.
Slim-компонент определяется с помощью декоратора
@customElement или функции Slim.define:
import { Slim, html, css, customElement } from '@slim-js/core';
@customElement('slim-counter')
class SlimCounter extends Slim {
static useShadow = true;
count = 0;
increment() {
this.count++;
}
render() {
return html`
Счётчик: ${this.count}
`;
}
}
Ключевые моменты:
@customElement('slim-counter') — регистрирует компонент
как HTML-элемент .useShadow = true — активирует Shadow DOM для
инкапсуляции стилей.render() — возвращает HTML-шаблон с использованием
реактивных данных.Slim-компоненты можно вставлять в шаблон Vue так же, как обычные HTML-элементы:
Vue и Slim.js
Vue автоматически рендерит Slim-компонент и корректно работает с его Shadow DOM, что позволяет объединять реактивность Vue и Slim.
Для передачи данных в Slim-компонент используется стандартная механика кастомных элементов через свойства и атрибуты:
@customElement('slim-greeter')
class SlimGreeter extends Slim {
name = 'Гость';
render() {
return html`Привет, ${this.name}!
`;
}
}
В Vue-шаблоне можно передать данные через атрибуты:
Для корректной реактивности атрибуты должны быть синхронизированы с свойствами Slim-компонента. Slim автоматически конвертирует строки в подходящий тип для свойства, если используется соответствующий декоратор или getter/setter.
Slim-компоненты могут генерировать кастомные события, которые Vue
легко обрабатывает через директиву v-on
(@):
@customElement('slim-button')
class SlimButton extends Slim {
handleClick() {
this.dispatchEvent(new CustomEvent('pressed', { detail: { time: Date.now() } }));
}
render() {
return html``;
}
}
В Vue-шаблоне подписка на событие выполняется так:
Это позволяет реализовывать двустороннее взаимодействие: Vue управляет состоянием, а Slim отвечает за локальные события и визуальную логику.
Slim-компоненты можно использовать вместе с реактивными объектами Vue
Composition API. Например, связывая данные через ref и
обновляя свойства Slim-компонента напрямую:
Таким образом можно комбинировать внутреннее состояние Slim с внешними данными Vue, сохраняя реактивность и модульность компонентов.
Slim-компоненты могут быть встроены в маршруты Vue Router как обычные элементы. Для Vuex можно использовать прямое присваивание свойств Slim-компонента из состояния хранилища:
computed: {
counterValue() {
return this.$store.state.counter;
}
},
watch: {
counterValue(newVal) {
this.$refs.slimCounter.count = newVal;
}
}
Это позволяет объединять централизованное управление состоянием Vue и локальные Slim-компоненты, обеспечивая гибкую архитектуру.
Slim.js использует виртуальный DOM и диффинг для обновления только
изменённых частей компонента. При интеграции с Vue стоит избегать
лишнего пересоздания Slim-компонентов через условные рендеры
(v-if), чтобы сохранить производительность. Предпочтение
стоит отдавать v-show или реактивному обновлению
свойств.
Slim позволяет изолировать стили с помощью Shadow DOM, что предотвращает конфликт CSS с Vue-компонентами. При необходимости глобальные стили можно применять через слоты или специальные CSS-переменные, передаваемые из Vue в Slim.