Slim.js предоставляет легковесный подход к созданию веб-компонентов с минимальной перегрузкой, сохраняя реактивность и простоту работы с DOM. Одним из ключевых аспектов современных веб-приложений является взаимодействие с удалёнными ресурсами через Fetch API, и интеграция его в компоненты Slim.js позволяет создавать динамические интерфейсы с асинхронными данными.
fetch — это встроенный в браузер метод для выполнения
HTTP-запросов. Его базовый синтаксис:
fetch(url, options)
.then(response => {
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
return response.json();
})
.then(data => {
// обработка полученных данных
})
.catch(error => {
console.error('Ошибка запроса:', error);
});
url — адрес ресурса.options — объект с настройками запроса: метод,
заголовки, тело и др.response.json() — преобразует ответ в объект JSON.catch.В компонентах Slim.js fetch можно использовать для
загрузки данных при инициализации компонента, при взаимодействии
пользователя или для периодического обновления информации.
Slim.js позволяет задать методы жизненного цикла компонента, такие
как onBeforeRender или onConnected, которые
идеально подходят для асинхронной загрузки данных. Пример компонента с
загрузкой данных при подключении к DOM:
class UserList extends Slim {
constructor() {
super();
this.users = [];
}
onConnected() {
this.loadUsers();
}
async loadUsers() {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/users');
if (!response.ok) throw new Error(`Ошибка загрузки: ${response.status}`);
this.users = await response.json();
this.update(); // обновление DOM
} catch (error) {
console.error('Не удалось загрузить пользователей:', error);
}
}
get template() {
return `
<ul>
${this.users.map(user => `<li>${user.name}</li>`).join('')}
</ul>
`;
}
}
customElements.define('user-list', UserList);
Ключевые моменты:
async/await упрощает работу с
асинхронными запросами.this.update() информирует Slim о необходимости
перерисовать компонент.В реальных приложениях важно показывать пользователю состояние загрузки и ошибки. Для этого можно использовать отдельные свойства компонента:
class PostsComponent extends Slim {
constructor() {
super();
this.posts = [];
this.loading = false;
this.error = null;
}
onConnected() {
this.fetchPosts();
}
async fetchPosts() {
this.loading = true;
this.error = null;
this.update();
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts');
if (!response.ok) throw new Error('Ошибка загрузки данных');
this.posts = await response.json();
} catch (err) {
this.error = err.message;
} finally {
this.loading = false;
this.update();
}
}
get template() {
if (this.loading) return `<p>Загрузка...</p>`;
if (this.error) return `<p>Ошибка: ${this.error}</p>`;
return `
<ul>
${this.posts.map(post => `<li>${post.title}</li>`).join('')}
</ul>
`;
}
}
customElements.define('posts-component', PostsComponent);
Особенности реализации:
loading позволяет показать индикатор процесса.error отображает текст ошибки.finally гарантирует, что состояние загрузки будет снято
вне зависимости от результата запроса.Slim.js поддерживает реактивность и двустороннюю привязку событий. Это позволяет делать запросы по действию пользователя, например, при нажатии кнопки или изменении значения поля:
class SearchUsers extends Slim {
constructor() {
super();
this.query = '';
this.results = [];
}
async search() {
if (!this.query) return;
try {
const response = await fetch(`https://api.example.com/users?search=${encodeURIComponent(this.query)}`);
if (!response.ok) throw new Error('Ошибка поиска');
this.results = await response.json();
this.update();
} catch (error) {
console.error(error);
}
}
onInputChange(event) {
this.query = event.target.value;
}
get template() {
return `
<input type="text" onin put="this.getSlim().onInputChange(event)" placeholder="Поиск пользователей" />
<button oncl ick="this.getSlim().search()">Найти</button>
<ul>
${this.results.map(user => `<li>${user.name}</li>`).join('')}
</ul>
`;
}
}
customElements.define('search-users', SearchUsers);
Особенности подхода:
onInputChange обновляет состояние query
при каждом вводе.this.getSlim() используется для доступа к методам Slim
внутри событийных атрибутов.Slim.js позволяет автоматически перерисовывать компонент при
изменении свойств. Использование реактивных свойств с fetch
повышает удобство:
class WeatherComponent extends Slim {
static get observedAttributes() { return ['city']; }
constructor() {
super();
this.city = '';
this.weather = null;
}
attributeChangedCallback(name, oldValue, newValue) {
if (name === 'city' && newValue !== oldValue) {
this.loadWeather(newValue);
}
}
async loadWeather(city) {
try {
const response = await fetch(`https://api.weatherapi.com/v1/current.json?key=API_KEY&q=${city}`);
this.weather = await response.json();
this.update();
} catch (error) {
console.error(error);
}
}
get template() {
if (!this.weather) return `<p>Введите город для получения прогноза</p>`;
return `
<h2>Погода в ${this.weather.location.name}</h2>
<p>Температура: ${this.weather.current.temp_c}°C</p>
<p>Состояние: ${this.weather.current.condition.text}</p>
`;
}
}
customElements.define('weather-component', WeatherComponent);
Особенности:
city автоматически
вызывает асинхронный запрос.this.update()..then() — код становится чище и легче
поддерживается.this.update(),
чтобы сохранить реактивность.Slim.js и Fetch API вместе позволяют строить компактные, динамичные компоненты с асинхронными данными, сохраняя чистоту кода и высокую производительность.