Stencil — это современный фреймворк для создания веб-компонентов, который позволяет разработчикам легко создавать повторно используемые элементы для интерфейсов. В отличие от традиционных фреймворков, таких как React или Angular, Stencil ориентирован на использование стандартов веб-компонентов, что позволяет интегрировать компоненты в проекты с различными технологическими стеками.
Каждый компонент в Stencil состоит из нескольких ключевых элементов: интерфейса, логики, стилей и тестов. Все эти части объединяются в единую структуру, которая помогает создавать функциональные и производительные компоненты.
Классовая структура Каждый компонент в Stencil
представляет собой класс, который наследуется от базового класса
Component. Этот класс содержит методы, описывающие
поведение компонента, а также ссылки на его состояние и
интерфейс.
Декораторы Stencil использует декораторы для
аннотирования классов и их методов. Наиболее важным декоратором является
@Component(), который описывает сам компонент. Декораторы
также используются для работы с пропсами, состоянием, событиями и
жизненным циклом компонента.
Рендеринг шаблона В Stencil шаблон компонента пишется с использованием JSX — синтаксиса, который похож на HTML, но позволяет вставлять логику JavaScript. JSX компилируется в JavaScript, что даёт разработчикам возможность динамически изменять DOM в зависимости от состояния компонента.
Каждый компонент в Stencil — это класс, который определяет его
поведение и внешний вид. Структура этого класса основывается на
JavaScript классе и декораторе @Component().
Пример компонента:
import { Component, h } from '@stencil/core';
@Component({
tag: 'my-component',
styleUrl: 'my-component.css',
shadow: true,
})
export class MyComponent {
render() {
return <div>Hello, World!</div>;
}
}
Stencil активно использует декораторы для аннотирования свойств и методов компонента. Наиболее важными являются:
@Component() — используется для объявления компонента. В декораторе указываются параметры, такие как имя тега, путь к стилям и необходимость использования Shadow DOM.
@Prop() — используется для объявления входных параметров компонента, которые могут быть установлены извне.
@State() — используется для создания локальных состояний, которые влияют на рендеринг компонента.
@Event() — используется для объявления событий, которые компонент может генерировать и которые могут быть обработаны родительским элементом.
Пример компонента с пропсами, состоянием и событиями:
import { Component, h, Prop, State, Event, EventEmitter } from '@stencil/core';
@Component({
tag: 'counter-component',
styleUrl: 'counter-component.css',
shadow: true,
})
export class CounterComponent {
@Prop() initialCount: number = 0;
@State() count: number = this.initialCount;
@Event() countChanged: EventEmitter;
increment() {
this.count++;
this.countChanged.emit(this.count);
}
render() {
return (
<div>
<button onCl ick={() => this.increment()}>Increment</button>
<p>Current count: {this.count}</p>
</div>
);
}
}
В этом примере:
@Prop() используется для получения значения свойства
initialCount, которое можно задать при использовании
компонента.@State() хранит текущее состояние счётчика, которое
обновляется при нажатии на кнопку.@Event() создаёт событие countChanged,
которое срабатывает при каждом изменении значения счётчика.Stencil предоставляет несколько методов жизненного цикла, которые помогают управлять состоянием компонента в разные моменты времени. Эти методы позволяют разработчикам контролировать, когда компоненты создаются, обновляются или уничтожаются.
componentWillLoad() — вызывается перед тем, как компонент будет загружен и отрендерен. Здесь можно выполнять асинхронные операции, такие как загрузка данных.
componentDidLoad() — вызывается после того, как компонент был загружен и отрендерен.
componentWillUpdate() — вызывается перед тем, как компонент будет обновлён, например, при изменении его состояния или пропсов.
componentDidUpdate() — вызывается после того, как компонент был обновлён.
componentWillUnload() — вызывается перед тем, как компонент будет удалён.
Пример использования жизненного цикла:
import { Component, h, State } from '@stencil/core';
@Component({
tag: 'lifecycle-demo',
styleUrl: 'lifecycle-demo.css',
shadow: true,
})
export class LifecycleDemo {
@State() data: string = '';
componentWillLoad() {
console.log('Component will load');
}
componentDidLoad() {
console.log('Component did load');
}
componentWillUpdate() {
console.log('Component will update');
}
componentDidUpdate() {
console.log('Component did update');
}
componentWillUnload() {
console.log('Component will unload');
}
render() {
return <div>{this.data}</div>;
}
}
Состояние компонента в Stencil хранится с помощью декоратора
@State(). Эти значения автоматически отслеживаются
фреймворком, и компоненты перерисовываются, когда состояние
изменяется.
Важно отметить, что изменения состояния происходят асинхронно, а обновление компонента не происходит немедленно, что помогает избежать лишних перерисовок.
Пример использования состояния:
import { Component, h, State } from '@stencil/core';
@Component({
tag: 'state-demo',
styleUrl: 'state-demo.css',
shadow: true,
})
export class StateDemo {
@State() count: number = 0;
increment() {
this.count++;
}
render() {
return (
<div>
<p>Current count: {this.count}</p>
<button onCl ick={() => this.increment()}>Increment</button>
</div>
);
}
}
Stencil позволяет компоновать интерфейсы с помощью пропсов и событий, что даёт гибкость в использовании и взаимодействии компонентов.
@Prop().@Event().Пример компонента с пропсами и событиями:
import { Component, h, Prop, Event, EventEmitter } from '@stencil/core';
@Component({
tag: 'user-card',
styleUrl: 'user-card.css',
shadow: true,
})
export class UserCard {
@Prop() name: string;
@Prop() age: number;
@Event() userClicked: EventEmitter;
handleClick() {
this.userClicked.emit({ name: this.name, age: this.age });
}
render() {
return (
<div onCl ick={() => this.handleClick()}>
<p>Name: {this.name}</p>
<p>Age: {this.age}</p>
</div>
);
}
}
В этом примере компонент UserCard принимает два пропса:
name и age, а также генерирует событие
userClicked, которое передает информацию о
пользователе.
Компоненты Stencil имеют четкую и структурированную анатомию, которая позволяет легко управлять их состоянием, взаимодействовать с другими частями приложения и обеспечить высокую производительность. Важными аспектами являются использование декораторов для работы с пропсами, состоянием и событиями, а также жизненный цикл компонента, который предоставляет возможности для оптимизации и асинхронной работы.