Stencil предоставляет разработчикам мощные инструменты для создания компонентов с использованием современных возможностей веб-технологий, включая поддержку списков и итераций. В этой главе рассматриваются основные подходы к работе с данными в виде списков, а также принципы и методы их итерации в компонентах Stencil.
В Stencil для работы с динамическими списками часто используется
конструкция циклов. Такой подход позволяет эффективно отображать
коллекции данных в HTML-разметке. Основной механизм для этого — это
встроенная директива @Watch, которая отслеживает изменения
данных и автоматически перерисовывает компонент.
Пример:
import { Component, h, State } from '@stencil/core';
@Component({
tag: 'item-list',
styleUrl: 'item-list.css',
shadow: true
})
export class ItemList {
@State() items: string[] = ['apple', 'banana', 'cherry'];
render() {
return (
<ul>
{this.items.map(item => (
<li>{item}</li>
))}
</ul>
);
}
}
В данном примере используется метод .map(), который
перебирает массив this.items и генерирует список
<li> для каждого элемента. Такой способ позволяет с
минимальными усилиями создать динамическое отображение данных.
Stencil использует реактивную модель данных, благодаря которой обновления списка автоматически отражаются в интерфейсе пользователя. Когда данные изменяются, Stencil следит за этим изменением и перерисовывает компонент без необходимости вручную управлять обновлениями DOM.
Для динамического изменения данных в списке можно использовать методы добавления и удаления элементов из состояния:
import { Component, h, State } from '@stencil/core';
@Component({
tag: 'dynamic-list',
styleUrl: 'dynamic-list.css',
shadow: true
})
export class DynamicList {
@State() items: string[] = [];
addItem(item: string) {
this.items = [...this.items, item];
}
removeItem(index: number) {
this.items = this.items.filter((_, i) => i !== index);
}
render() {
return (
<div>
<ul>
{this.items.map((item, index) => (
<li>
{item}
<button onCl ick={() => this.removeItem(index)}>Удалить</button>
</li>
))}
</ul>
<button onCl ick={() => this.addItem('новый элемент')}>Добавить элемент</button>
</div>
);
}
}
В этом примере добавление и удаление элементов из списка происходит с
использованием реактивных методов addItem и
removeItem, что автоматически обновляет DOM, поскольку
Stencil отслеживает изменения в @State().
Когда работаешь с итерациями, особенно в случаях, когда элементы могут изменяться, важно использовать уникальные ключи для каждого элемента в списке. Это помогает Stencil эффективно обновлять только те элементы, которые были изменены, без перерасчета всего списка.
Stencil позволяет использовать атрибут key, чтобы
присвоить уникальные идентификаторы каждому элементу списка:
render() {
return (
<ul>
{this.items.map(item => (
<li key={item}>{item}</li>
))}
</ul>
);
}
Использование ключей значительно повышает производительность, особенно если список большой или элементы списка часто обновляются. Это позволяет избежать лишних операций по обновлению и перерисовке элементов.
Иногда данные в списке поступают асинхронно — например, из API. В
таких случаях стоит учесть, что Stencil позволяет интегрировать
асинхронные запросы с компонентами через использование
@State или @Prop.
Пример загрузки данных из API и отображения их в списке:
import { Component, h, State } from '@stencil/core';
@Component({
tag: 'async-list',
styleUrl: 'async-list.css',
shadow: true
})
export class AsyncList {
@State() items: string[] = [];
async componentWillLoad() {
const response = await fetch('https://api.example.com/items');
const data = await response.json();
this.items = data.items;
}
render() {
return (
<ul>
{this.items.map(item => (
<li>{item}</li>
))}
</ul>
);
}
}
В этом примере при загрузке компонента выполняется асинхронный запрос к API, данные из которого затем сохраняются в состоянии компонента. После получения данных происходит их отрисовка в списке.
Stencil также поддерживает итерации не только по массивам, но и по
объектам. Для работы с объектами можно использовать методы, которые
позволяют преобразовывать объект в массив, например,
Object.entries().
Пример:
render() {
const data = {
apple: 1,
banana: 2,
cherry: 3,
};
return (
<ul>
{Object.entries(data).map(([key, value]) => (
<li>{key}: {value}</li>
))}
</ul>
);
}
Здесь Object.entries(data) преобразует объект в массив
пар ключ-значение, и в цикле отображаются каждый ключ и его
значение.
Списки в Stencil можно не только отображать, но и модифицировать до их отображения. Для этого удобно использовать фильтрацию, сортировку и другие операции с массивами.
Пример сортировки и фильтрации списка:
import { Component, h, State } from '@stencil/core';
@Component({
tag: 'filtered-list',
styleUrl: 'filtered-list.css',
shadow: true
})
export class FilteredList {
@State() items: string[] = ['apple', 'banana', 'cherry', 'orange'];
render() {
const filteredItems = this.items.filter(item => item.startsWith('b')).sort();
return (
<ul>
{filteredItems.map(item => (
<li>{item}</li>
))}
</ul>
);
}
}
В данном примере список сначала фильтруется по элементам, начинающимся на букву “b”, а затем сортируется в алфавитном порядке перед тем, как отобразиться.
Stencil позволяет легко создавать вложенные компоненты, что полезно при работе с иерархическими данными. Используя повторяющиеся компоненты внутри других компонентов, можно строить сложные интерфейсы.
Пример вложенного компонента:
import { Component, h, Prop } from '@stencil/core';
@Component({
tag: 'item-detail',
styleUrl: 'item-detail.css',
shadow: true
})
export class ItemDetail {
@Prop() item: string;
render() {
return <div>Подробности: {this.item}</div>;
}
}
@Component({
tag: 'item-list',
styleUrl: 'item-list.css',
shadow: true
})
export class ItemList {
@State() items: string[] = ['apple', 'banana', 'cherry'];
render() {
return (
<ul>
{this.items.map(item => (
<li>
{item}
<item-detail item={item}></item-detail>
</li>
))}
</ul>
);
}
}
В этом примере внутри каждого элемента списка рендерится компонент
item-detail, который отображает дополнительную информацию о
каждом элементе. Это показывает, как можно строить сложные компоненты с
вложенной логикой и визуальными элементами.
Итерации в Stencil обеспечивают гибкость и простоту при работе с динамическими данными. С помощью методов отображения списков, фильтрации, сортировки и асинхронных запросов можно легко строить мощные и эффективные интерфейсы.