Stencil — это современный фреймворк для создания веб-компонентов с использованием стандартных технологий, таких как HTML, CSS и JavaScript. Одной из ключевых особенностей Stencil является поддержка декораторов, которые упрощают работу с компонентами и делают код более читаемым и удобным для поддержки.
Декоратор @Prop в Stencil используется для объявления
входных свойств (пропсов) компонента. Это позволяет передавать данные от
родительского компонента к дочернему. Важно отметить, что свойства,
отмеченные с помощью @Prop, становятся доступными для
внешнего мира и могут быть установлены извне, а также изменяться.
Декоратор @Prop позволяет указать, что свойство
компонента будет получать значение извне, что делает его частью API
компонента. Пропсы — это механизмы, которые обеспечивают динамическую
передачу данных между компонентами.
Пример использования @Prop для простого компонента:
import { Component, Prop, h } from '@stencil/core';
@Component({
tag: 'my-greeting',
styleUrl: 'my-greeting.css',
shadow: true,
})
export class MyGreeting {
@Prop() name: string;
render() {
return <p>Hello, {this.name}!</p>;
}
}
В данном примере компонент my-greeting имеет пропс
name, который будет передаваться извне и использоваться для
отображения приветствия. Внутри компонента пропс доступен как обычное
свойство класса.
Stencil позволяет задавать типы данных для пропсов, что помогает
предотвратить ошибки и улучшить читаемость кода. В качестве типов можно
использовать стандартные JavaScript-типизации, такие как
string, number, boolean, а также
более сложные структуры, например, Array или
Object.
@Component({
tag: 'my-product',
styleUrl: 'my-product.css',
shadow: true,
})
export class MyProduct {
@Prop() name: string;
@Prop() price: number;
@Prop() inStock: boolean;
render() {
return (
<div>
<h2>{this.name}</h2>
<p>Price: ${this.price}</p>
<p>{this.inStock ? 'In Stock' : 'Out of Stock'}</p>
</div>
);
}
}
В этом примере пропсы имеют типы: name — строка,
price — число, а inStock — булевое значение.
Использование правильных типов позволяет избежать ошибок, связанных с
неправильной передачей данных в компонент.
Stencil поддерживает установку значений по умолчанию для пропсов. Это позволяет задавать начальные значения для свойств, если родительский компонент не передает их явно.
@Component({
tag: 'my-user',
styleUrl: 'my-user.css',
shadow: true,
})
export class MyUser {
@Prop() name: string = 'Guest';
@Prop() age: number = 18;
render() {
return (
<div>
<h1>{this.name}</h1>
<p>Age: {this.age}</p>
</div>
);
}
}
В данном примере, если родительский компонент не передаст значение
для name или age, компоненты будут отображать
Guest и 18 соответственно.
Stencil автоматически отслеживает изменения значений пропсов и перерисовывает компонент при их изменении. Это позволяет компонентам быть реактивными, обновляя отображаемое содержимое, когда пропсы изменяются.
Чтобы добавить дополнительную логику при изменении пропсов, можно
использовать метод жизненного цикла componentWillLoad или
componentDidUpdate. Например, если нужно выполнить действие
после того, как пропс изменился, можно сделать это следующим
образом:
@Component({
tag: 'my-counter',
styleUrl: 'my-counter.css',
shadow: true,
})
export class MyCounter {
@Prop() count: number;
componentDidUpdate() {
console.log(`Count has been updated to: ${this.count}`);
}
render() {
return <div>{this.count}</div>;
}
}
Этот код позволит отслеживать каждое изменение значения пропса
count и выводить его в консоль.
Stencil поддерживает несколько модификаторов для пропсов, которые
могут изменять их поведение. Один из самых популярных — это
reflectToAttr, который позволяет синхронизировать значение
пропса с атрибутом в DOM.
@Component({
tag: 'my-checkbox',
styleUrl: 'my-checkbox.css',
shadow: true,
})
export class MyCheckbox {
@Prop({ reflect: true }) checked: boolean;
render() {
return <input type="checkbox" checked={this.checked} />;
}
}
Здесь, благодаря reflect: true, значение пропса
checked будет автоматически синхронизироваться с атрибутом
checked в DOM. Это означает, что если состояние пропса
изменится, это изменение отобразится и на атрибуте.
Пропсы в Stencil играют ключевую роль в рендеринге компонентов. Они позволяют динамически изменять содержимое компонента в зависимости от внешних данных. При этом важно помнить, что компоненты в Stencil могут рендериться как через шаблонный синтаксис JSX, так и через стандартный HTML.
Пример:
@Component({
tag: 'my-alert',
styleUrl: 'my-alert.css',
shadow: true,
})
export class MyAlert {
@Prop() message: string;
@Prop() type: string = 'info';
render() {
return (
<div class={`alert alert-${this.type}`}>
<span>{this.message}</span>
</div>
);
}
}
В этом компоненте, в зависимости от значения пропса
type, будет изменяться класс alert, что
позволяет стилизовать компонент по-разному для различных типов сообщений
(например, для ошибок, предупреждений или информационных сообщений).
Stencil также поддерживает более сложные типы данных для пропсов, такие как массивы или объекты. В этом случае важно правильно обрабатывать эти данные внутри компонента.
Пример использования объекта:
@Component({
tag: 'my-profile',
styleUrl: 'my-profile.css',
shadow: true,
})
export class MyProfile {
@Prop() user: { name: string; age: number; location: string };
render() {
return (
<div>
<h1>{this.user.name}</h1>
<p>Age: {this.user.age}</p>
<p>Location: {this.user.location}</p>
</div>
);
}
}
Здесь пропс user представляет собой объект с несколькими
полями. Важно убедиться, что передаваемый объект имеет правильную
структуру, чтобы избежать ошибок в рендеринге.
Использование декоратора @Prop в Stencil позволяет легко
работать с входными данными, которые могут быть переданы в компонент
извне. Это упрощает создание динамичных и реактивных компонентов,
улучшая взаимодействие между компонентами и позволяя управлять
состоянием на уровне API компонента.