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

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

Это мой-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>
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
152
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

И да и нет.

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

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. Я нахожу это раздражающим. Большинство моих компонентов очень маленькие и не нуждаются в сложности.

Расширенный

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

Вместо:

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

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

ОБНОВИТЬ

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

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

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

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

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

могу ли я также передавать функции (может быть, также в виде строки) компоненту?

Andreas 10.05.2019 08:38

Смотрите мой развернутый ответ. Можете ли вы предоставить более подробную информацию о том, что вы хотите сделать с функцией.

Intervalia 10.05.2019 15:41

Расширенный ответ абсолютно подходит для того, что я хочу сделать. Спасибо :)

Andreas 10.05.2019 15:42

Есть ли способ предотвратить двойной вызов render(this) при установке двух атрибутов подряд.

sabithpocker 08.06.2019 00:58

см. мое обновление для одного из способов «отменить дребезг» функциональности.

Intervalia 08.06.2019 17:16

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