{@attach ...}
Привязки (attachments) — это функции, которые выполняются при монтировании элемента в DOM. При необходимости они могут возвращать функцию, которая будет вызвана при удалении элемента из DOM.
<script> /** @type {import('svelte/attachments').Attachment} */ function myAttachment(element) { console.log(element.nodeName); // 'DIV'
return () => { console.log('cleaning up'); }; }</script>
<div {@attach myAttachment}>...</div>
<script lang="ts"> import type { Attachment } from 'svelte/attachments';
const myAttachment: Attachment = (element) => { console.log(element.nodeName); // 'DIV'
return () => { console.log('cleaning up'); }; };</script>
<div {@attach myAttachment}>...</div>
Элемент может иметь любое количество привязок.
Фабрики привязок
Заголовок раздела «Фабрики привязок»Полезный паттерн — когда функция (например, tooltip
в этом примере) возвращает привязку (демонстрация):
<script> import tippy from 'tippy.js';
let content = $state('Hello!');
/** * @param {string} content * @returns {import('svelte/attachments').Attachment} */ function tooltip(content) { return (element) => { const tooltip = tippy(element, { content }); return tooltip.destroy; }; }</script>
<input bind:value={content} />
<button {@attach tooltip(content)}> Наведи курсор</button>
<script lang="ts"> import tippy from 'tippy.js'; import type { Attachment } from 'svelte/attachments';
let content = $state('Hello!');
function tooltip(content: string): Attachment { return (element) => { const tooltip = tippy(element, { content }); return tooltip.destroy; }; }</script>
<input bind:value={content} />
<button {@attach tooltip(content)}> Наведи курсор</button>
Поскольку выражение tooltip(content)
выполняется внутри эффекта, привязка будет уничтожаться и создаваться заново при каждом изменении content
.
Встроенные привязки
Заголовок раздела «Встроенные привязки»Привязки также можно создавать встроенным способом (демонстрация):
<script> import { paint } from './gradient.js';</script>
<canvas width={32} height={32} {@attach (canvas) => { const context = canvas.getContext('2d');
$effect(() => { let frame = requestAnimationFrame(function loop(t) { frame = requestAnimationFrame(loop); paint(context, t); });
return () => { cancelAnimationFrame(frame); }; }); }}></canvas>
<script lang="ts"> import { paint } from './gradient.js';</script>
<canvas width={32} height={32} {@attach (canvas) => { const context = canvas.getContext('2d');
$effect(() => { let frame = requestAnimationFrame(function loop(t) { frame = requestAnimationFrame(loop); paint(context, t); });
return () => { cancelAnimationFrame(frame); }; }); }}></canvas>
Передача привязок в компоненты
Заголовок раздела «Передача привязок в компоненты»При использовании {@attach ...}
на компоненте создаётся проп с ключом-Symbol
. Если компонент затем распространяет пропсы на элемент, этот элемент получит привязки.
Это позволяет создавать обёрточные компоненты, расширяющие функциональность элементов (демонстрация):
<script> /** @type {import('svelte/elements').HTMLButtonAttributes} */ let { children, ...props } = $props();</script>
<!-- `props` включает привязки --><button {...props}> {@render children?.()}</button>
<script lang="ts"> import type { HTMLButtonAttributes } from 'svelte/elements';
let { children, ...props }: HTMLButtonAttributes = $props();</script>
<!-- `props` включает привязки --><button {...props}> {@render children?.()}</button>
<script> import tippy from 'tippy.js'; import Button from './Button.svelte';
let content = $state('Hello!');
/** * @param {string} content * @returns {import('svelte/attachments').Attachment} */ function tooltip(content) { return (element) => { const tooltip = tippy(element, { content }); return tooltip.destroy; }; }</script>
<input bind:value={content} />
<Button {@attach tooltip(content)}> Наведи курсор</Button>
<script lang="ts"> import tippy from 'tippy.js'; import Button from './Button.svelte'; import type { Attachment } from 'svelte/attachments';
let content = $state('Hello!');
function tooltip(content: string): Attachment { return (element) => { const tooltip = tippy(element, { content }); return tooltip.destroy; }; }</script>
<input bind:value={content} />
<Button {@attach tooltip(content)}> Наведи курсор</Button>
Программное создание привязок
Заголовок раздела «Программное создание привязок»Для добавления привязок к объекту, который будет распространён на компонент или элемент, используйте createAttachmentKey
.
Преобразование действий в привязки
Заголовок раздела «Преобразование действий в привязки»Если вы используете библиотеку, которая предоставляет только действия, вы можете преобразовать их в привязки с помощью fromAction
, что позволяет, например, использовать их с компонентами.