Можно ли внедрить пользовательские атрибуты / свойства в нативные веб-компоненты? - PullRequest
1 голос
/ 26 апреля 2019

Я изучаю веб-компоненты (нативные и с фреймворками).Можно ли внедрить свойства в собственный компонент, как я могу сделать, например, в Vue.js?

Это my-component.js:

const templateComponent = document.createElement('template');
templateComponent.innerHTML = `<div>{{ test }}</div>`;

class MyComponent extends HTMLElement {

    connectedCallback() {
        this._container = this.querySelector("DIV");
    }

}

window.customElements.define("my-component", MyComponent);

Это index.html:

<!doctype html>
<html lang="en">
<head>
    <title>Document</title>
</head>
<body>

<my-component test="Does this work?"></my-component>


<script src="my-component.js"></script>

</body>
</html>

1 Ответ

1 голос
/ 26 апреля 2019

Да и нет.

В шаблонах нет ничего встроенного.Но это не значит, что вы не можете этого сделать.

function render(el) {
  el.shadowRoot.innerHTML = `<div>${el._test}</div>`;
}

class MyComponent extends HTMLElement {
  static get observedAttributes() {
    return ['test'];
  }

  constructor() {
    super();
    this.attachShadow({mode: 'open'});
  }

  attributeChangedCallback(attrName, oldVal, newVal) {
    if (oldVal !== newVal) {
      this[`_${attrName}`] = newVal;
      render(this);
    }
  }
}

window.customElements.define("my-component", MyComponent);
<my-component test="Does this work?"></my-component>
<my-component test="Yes it does"></my-component>

Вы используете observedAttributes, чтобы указать, какие атрибуты вы хотите наблюдать за изменениями.И вы используете attributeChangedCallback в качестве обработчика для случая, когда один из них действительно изменяется.

Тогда вы можете получить значение атрибута в DOM.Если DOM прост, вы можете делать то же, что и я, и просто каждый раз обновлять его.

Для чего-то более сложного потребуется более сложный алгоритм.

Некоторые люди скажут вам использовать LITHtml.Я нахожу это раздражающим.Большинство моих компонентов очень маленькие и не нуждаются в сложности.

Extended

Да, вы можете передать функцию обратного вызова в виде строки.Другими словами, вы передаете имя функции обратного вызова в виде строки, а затем в своем компоненте вызываете eval. НО Я бы не советовал.Это имеет множество ограничений и может быть использовано в злых и гнусных целях.:)

Вместо этого:

  • Предоставить свойство компонента, которое можно установить для функции обратного вызова.
  • Предоставить функцию для компонента, который будет вызыватьсяс вашей функцией обратного вызова
  • Отправляйте события из компонента и позвольте addEventListener обработать его для вас.Можете ли вы предоставить более подробную информацию о том, что вы хотите сделать с помощью функции

Вот два полезных вопроса / ответа: * Пользовательская функция обратного вызова события веб-компонента в теге * Могу ли я передать функцию в качестве атрибута веб-компоненту?

ОБНОВЛЕНИЕ

Был задан вопрос, как избежать рендеринга чаще, чем необходимо, когда несколько атрибутов или свойствБыли установлены.Это часто называют «debouncing».

Вот один из вариантов:

let renderTimeout = null;
function render(el) {
  if (renderTimeout) {
    clearTimeout(renderTimeout);
  }

  renderTimeout = setTimeout(() => {
    el.shadowRoot.innerHTML = `<div>${el._test}</div>`;
  }, 0);
}

Это установит тайм-аут на 0, что означает, что это произойдет, как только он сможет,часто, как только текущий код закончил работу.Тогда произойдет операция рендеринга.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...