#web-component #html-templates
#веб-компонент #html-шаблоны
Вопрос:
Кажется, я не могу понять или понять, почему вы должны использовать шаблоны HTML с веб-компонентами, когда вы можете просто определить HTML внутри веб-компонента (shadowRoot.innerHTML).
В чем преимущество создания шаблона и его клонирования внутри веб-компонента? Я вижу, что есть причина, если два веб-компонента используют один и тот же HTML, но помимо этого я понятия не имею.
Есть ли что-то принципиально важное, чего мне не хватает?
Ответ №1:
Да, слишком много блогов делают document.createElement("template")
то же самое, где an .innerHTML
будет делать то же самое… и с меньшим количеством кода… и быстрее.
Обратите внимание, что шаблоны не привязаны к API пользовательских элементов или ShadowDOM.
Каждая из 3 технологий веб-компонентов может использоваться без другой.
Шаблоны
Шаблоны хороши, когда вы хотите сохранить повторно используемый контент в HTML-документе, потому что он не анализируется.
В старые времена мы использовали a <div hidden>
и молились, чтобы его содержимое не влияло на остальную часть страницы.
Как и в старые времена, вы можете прочитать Template.innerHTML и делать со строковым значением все, что хотите.
Более современный подход заключается в клонировании шаблона, просто имейте в виду, что .content
требуется свойство, и вы получаете взамен значение фрагмента документа.
<template id="MY-TEMPLATE">
<article>
...
</article>
</template>
document.getElementById("MY-TEMPLATE").content.cloneNode(true)
Шаблоны и ShadowDOM
Когда у вас есть пользовательские элементы с ShadowDOM, шаблоны отлично подходят для определения этого содержимого ShadowDOM.
Почему так много разработчиков хотят создавать HTML-in-JS и CSS-in-JS, я не понимаю.
Если у вас есть HTML-документ, сохраните его содержимое там, его будет проще редактировать.
<template id="MY-ELEMENT">
<style>
/* style shadowDOM here */
</style>
<slot></slot>
</template>
Тогда все, что нужно сделать вашему MY-ELEMENT, это:
super() // or this when done in the connectedCallback
.attachShadow({mode: 'open'})
.append(document.getElementById(this.nodeName).content.cloneNode(true))
Производительность
Строка innerHTML с содержимым HTML будет анализироваться при каждом использовании.
Шаблон анализируется один раз, поэтому при многократном использовании одного и того же шаблона экономятся циклы процессора
Но, как уже было сказано, большинство блогов используют шаблон один раз.
Использование
Мое личное предпочтение — сохранить как можно больше HTML (и CSS) <TEMPLATEs>
внутри HTML. Только когда я хочу, чтобы мои компоненты не настраивались, я использую статический HTML в JS, с .innerHTML
, а не .createElement("template")
потому, что это одноразовая инъекция HTML
Только в SDWCS (самоуничтожающиеся веб-компоненты), которые необходимо загрузить / выполнить как можно скорее, я содержу все внутри компонента:
customElements.define('my-head',class extends HTMLElement{
connectedCallback(){
// generate <HEAD> content, <SCRIPTS> and <STYLE> CSS-in-JS here
this.remove();
}
});
Комментарии:
1. Дэнни, ты помог мне больше, чем ты когда-либо знаешь, изучить веб-компоненты. Вы герой веб-компонента в stack overflow. Мне действительно нравится ваш стиль и перспективы. Я смотрел на litelement (поскольку большинство блогов и видео указывают в этом направлении), но, увидев один из ваших комментариев, я придерживаюсь vanilla JS.
2. Я согласен и тоже использую шаблоны, но проблема в том, как теперь связать HTML с JS, которые
HTML imports
были обесценены. Сохранение всего этого в JS (хотя и медленнее) имеет преимущество в переносимости3. В JS вы определяете HTML как текстовые строки
Ответ №2:
В чем преимущество создания шаблона и его клонирования внутри веб-компонента?
Скорость. Разбор строки и создание внутренних объектов html занимает некоторое дополнительное время по сравнению с простым клонированием узлов. Если веб-компонент используется во многих местах, и каждый из них будет анализировать строку и преобразовывать ее в объекты html. Сравните это с одним синтаксическим анализом.