Доступ к сгенерированному пользовательскому элементу в 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

Другие вопросы по тегам