Доступ к сгенерированному пользовательскому элементу в Svelte 3
Я использую Svelte 3 с возможностью создания пользовательских элементов с помощью Shadow DOM, но не могу понять, как получить ссылку на пользовательский элемент-оболочку (HTMLElement), чтобы я мог прикреплять обработчики событий и манипулировать атрибутами. У меня есть что-то вроде этого:
<svelte:options tag="custom-button"/>
<script>
import { onMount } from 'svelte';
function _onClick(e) {
this.setAttribute('pressed', null);
}
var _boundClick = _onClick.bind(this);
onMount((e) => {
this.addEventListener('click', _boundClick);
return () => {
this.removeEventListener('click', _boundClick);
};
});
</script>
<style>
:host {
display: block;
}
/* Other Styling */
</style>
<slot></slot>
Биты "this" не работают (они работают в обычном элементе Custom Vanilla). Есть ли какой-то специфический способ Svelte для получения ссылки на элемент host в скрипте?
Спасибо
4 ответа
В настоящее время это невозможно напрямую, хотя это было бы полезным дополнением. Я только что поднял вопрос.
Косвенным подходом было бы сделать bind:this={element}
на элемент верхнего уровня внутри вашего пользовательского элемента (при условии, что у вас есть один), то вы можете сделать что-то длинное строки $: host = element && element.parentNode.host
, У вас не будет доступа к нему при инициализации, но он будет готов в onMount
,
Я думаю, что вы хотите создать элемент, который окружает слот, а затем связать его с переменной, используя bind:this={var}
как показано в этом примере: https://svelte.dev/docs
так что-то вроде
<custom-button bind:this={customButton}>
<slot></slot>
</custom-button>
Затем используйте эту связанную переменную (customButton
), что в JavaScript, а не this
вот так:
let customButton;
function _onClick(e) {
customButton.setAttribute('pressed', null);
}
И так далее
Одно из возможных решений - использовать функцию get_current_component из svelte/internal
import { get_current_component } from 'svelte/internal';
let host = get_current_component();
Я думаю, что экспорт этой функции был бы очень полезен.
Сейчас для этого есть хорошее решение в ветке проблем, на которую Рич Харрис ссылался выше.
Для этого вы можете использовать опцию «расширить» customElement:
<svelte:options
customElement={{
tag: 'custom-element',
extend: (customElementConstructor) => {
return class extends customElementConstructor {
constructor() {
super();
this.host = this; // or this.shadowRoot, or whatever you need
}
};
}
}}
/>
<script>
export let host;
</script>
Скопировано из этого комментария "dummdidumm": https://github.com/sveltejs/svelte/issues/3091#issuecomment-1642351615