Awesomplete представляет собой минималистичную, но функционально гибкую библиотеку автодополнения, изначально рассчитанную на работу с «чистым» DOM. При использовании в реактивных фреймворках, таких как Svelte, требуется учитывать особенности жизненного цикла компонентов и реактивности, чтобы корректно синхронизировать внешний DOM-объект с состоянием приложения.
Svelte компилирует компоненты в императивный код, напрямую работающий с DOM, поэтому интеграция Awesomplete проходит проще, чем в более абстрактных фреймворках. Тем не менее, библиотека не является реактивной по своей природе, и её состояние необходимо синхронизировать вручную.
Установка библиотеки:
npm install awesomplete
Подключение стилей:
import "awesomplete/awesomplete.css";
Импорт самой библиотеки:
import Awesomplete from "awesomplete";
Awesomplete требует наличия DOM-элемента <input>,
поэтому инициализация должна происходить после монтирования
компонента.
Ключевой механизм интеграции — использование onMount,
обеспечивающего доступ к DOM.
<script>
import { onMount } from "svelte";
import Awesomplete from "awesomplete";
import "awesomplete/awesomplete.css";
let input;
let awesomplete;
const list = ["Apple", "Apricot", "Banana", "Blueberry", "Cherry"];
onMount(() => {
awesomplete = new Awesomplete(input, {
list,
minChars: 1,
maxItems: 10,
autoFirst: true
});
});
</script>
<input bind:this={input} placeholder="Введите фрукт" />
bind:this используется для получения ссылки на
DOM-элемент.onMount гарантирует, что элемент уже существует.Awesomplete не отслеживает изменения массива автоматически. Любое изменение данных требует ручного обновления.
list<script>
import { onMount } from "svelte";
import Awesomplete from "awesomplete";
let input;
let awesomplete;
let fruits = ["Apple", "Banana", "Cherry"];
function updateList() {
if (awesomplete) {
awesomplete.list = fruits;
}
}
onMount(() => {
awesomplete = new Awesomplete(input, {
list: fruits
});
});
function addFruit() {
fruits = [...fruits, "Orange"];
updateList();
}
</script>
<input bind:this={input} />
<button on:click={addFruit}>Добавить</button>
Awesomplete хранит копию списка внутри экземпляра, поэтому изменение массива Svelte само по себе не вызывает обновления автодополнения.
Часто список формируется на основе API или вычислений. В таком случае важна синхронизация при изменении переменных.
<script>
import { onMount } from "svelte";
import Awesomplete from "awesomplete";
let input;
let awesomplete;
let query = "";
let items = [];
$: filtered = items.filter(i =>
i.toLowerCase().includes(query.toLowerCase())
);
$: if (awesomplete) {
awesomplete.list = filtered;
}
onMount(() => {
awesomplete = new Awesomplete(input, {
list: filtered,
minChars: 1
});
});
</script>
<input bind:this={input} bind:value={query} />
$:Svelte позволяет автоматически отслеживать изменения и обновлять
awesomplete.list.
При работе с серверными источниками данных важно учитывать задержки и состояние пустого списка.
<script>
import { onMount } from "svelte";
import Awesomplete from "awesomplete";
let input;
let awesomplete;
let cities = [];
async function loadCities() {
const res = await fetch("/api/cities");
cities = await res.json();
if (awesomplete) {
awesomplete.list = cities;
}
}
onMount(() => {
awesomplete = new Awesomplete(input, {
list: []
});
loadCities();
});
</script>
<input bind:this={input} />
Awesomplete предоставляет набор опций, которые могут быть адаптированы под реактивную среду Svelte.
awesomplete = new Awesomplete(input, {
list,
minChars: 2,
maxItems: 5,
autoFirst: true,
filter: (text, input) => {
return text.includes(input);
},
item: (text, input) => {
return Awesomplete.ITEM(text, input);
}
});
minChars — минимальное количество символов для
активации.maxItems — ограничение числа отображаемых
элементов.filter — кастомная логика фильтрации.item — кастомный рендер элемента списка.В Svelte важно контролировать жизненный цикл сторонних библиотек, чтобы избежать утечек и дублирования экземпляров.
<script>
import { onMount, onDestroy } from "svelte";
import Awesomplete from "awesomplete";
let input;
let awesomplete;
onMount(() => {
awesomplete = new Awesomplete(input, {
list: ["A", "B", "C"]
});
});
onDestroy(() => {
awesomplete = null;
});
</script>
<input bind:this={input} />
Awesomplete не предоставляет полноценного метода destroy, поэтому освобождение ссылки предотвращает утечки в SPA.
Awesomplete генерирует события, которые можно использовать в Svelte
через addEventListener.
<script>
import { onMount } from "svelte";
import Awesomplete from "awesomplete";
let input;
let awesomplete;
onMount(() => {
awesomplete = new Awesomplete(input, {
list: ["JavaScript", "TypeScript", "Svelte"]
});
input.addEventListener("awesomplete-selectcomplete", (e) => {
console.log("Выбран элемент:", e.text.value);
});
});
</script>
<input bind:this={input} />
awesomplete-selectcomplete — выбор элемента.awesomplete-open — открытие списка.awesomplete-close — закрытие списка.Svelte позволяет реализовать более высокоуровневую абстракцию над Awesomplete, превращая его в управляемый компонент.
<script>
import { onMount } from "svelte";
import Awesomplete from "awesomplete";
export let items = [];
export let value = "";
let input;
let awesomplete;
$: if (awesomplete) {
awesomplete.list = items;
}
onMount(() => {
awesomplete = new Awesomplete(input, {
list: items
});
input.addEventListener("awesomplete-selectcomplete", (e) => {
value = e.text.value;
});
});
</script>
<input bind:this={input} bind:value={value} />
Awesomplete работает напрямую с DOM и не использует виртуальное дерево, что делает его быстрым в большинстве сценариев. Однако при частых обновлениях списка в реактивной системе важно учитывать стоимость перерисовки:
list лучше выполнять батчами;list, а не пересоздавать
Awesomplete.В Svelte часто целесообразно вынести Awesomplete в отдельный слой логики, чтобы компонент оставался декларативным.
function createAutocomplete(input, list) {
const instance = new Awesomplete(input, { list });
return {
setList(newList) {
instance.list = newList;
},
destroy() {
instance = null;
}
};
}
Такая структура позволяет отделить UI от механики автодополнения и упрощает поддержку сложных форм.
При использовании Svelte-форм Awesomplete работает поверх
стандартного <input> без вмешательства в механизм
bind:value, однако важно учитывать:
value через binding;Типичная стратегия — доверять DOM как источнику истины для значения input, а Svelte использовать для внешнего состояния формы.