У меня есть пользовательский компонент, который просто показывает карту Таро. Перед пользовательским элементом я определил шаблон.
В подключенном обратном вызове моего wc я прикрепил сам шаблон к теневому корню, а затем удалил его, клонировав его там же в теневой корень. Я сделал это по 2 причинам:

  1. Я хочу, чтобы мой wc-компонент был автономным модулем; поэтому я хочу определить свой шаблон в том же месте, что и мой пользовательский элемент.
  2. Кажется, это единственный способ удалить мой шаблон, чтобы сделать его пригодным для использования, не вставляя его в документ владельца.

    var tmpl = ` {amp}lt;template id="tmpl"{amp}gt; {amp}lt;h1 class="tarot-title"{amp}gt;{amp}lt;slot name="title"{amp}gt;NEED TITLE{amp}lt;/slot{amp}gt; {amp}lt;/h1{amp}gt; {amp}lt;img src="${this.imageurl}" alt="Как штамповать шаблон в автономных пользовательских элементов с Vanilla JS?"{amp}gt; {amp}lt;p{amp}gt;{amp}lt;slot name="subtitle"{amp}gt;NEED A SUBTITLE{amp}lt;/slot{amp}gt;{amp}lt;/p{amp}gt; {amp}lt;/template{amp}gt;`; class BdTarot extends HTMLElement { ...constructor etc... connectedCallback() { this._shadowRoot.innerHTML = tmpl; var _tmpl = this._shadowRoot.querySelector('#tmpl'); this._shadowRoot.appendChild(_tmpl.content.cloneNode(true)); } } customElements.define('bd-tarot', BdTarot); 

Проблема, которую это создало, состоит в том, что каждый компонент карты Таро, который я использую на своей странице, имеет один и тот же шаблон — дочерний, с одинаковым идентификатором. Раз они в тени корней, это имеет значение? Хотя пахнет смешно …

Моя цель — просто попытаться понять, как все спецификации веб-компонентов сочетаются друг с другом. У меня вопрос, есть ли лучший способ сделать это, чтобы сохранить код моего компонента вместе и не ссылаться на документ владельца? Является ли спецификация шаблона в основном несовместимой с пользовательскими элементами, поскольку импорт html не принимается большинством поставщиков браузеров?

В двух словах: если вы используете литералы шаблона, то вам не следует использовать элемент {amp}lt;template{amp}gt; .

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

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

 (function () { var tmpl = ` {amp}lt;h1 class="tarot-title"{amp}gt;{amp}lt;slot name="title"{amp}gt;NEED TITLE{amp}lt;/slot{amp}gt;{amp}lt;/h1{amp}gt; {amp}lt;img src="${this.imageurl}" alt="Как штамповать шаблон в автономных пользовательских элементов с Vanilla JS?"{amp}gt; {amp}lt;p{amp}gt;{amp}lt;slot name="subtitle"{amp}gt;NEED A SUBTITLE{amp}lt;/slot{amp}gt;{amp}lt;/p{amp}gt;`; class BdTarot extends HTMLElement { constructor() { super() this.attachShadow( { mode: 'open' } ) .innerHTML = tmpl; } } customElements.define('bd-tarot', BdTarot); })() 
 {amp}lt;bd-tarot{amp}gt; {amp}lt;span slot="title"{amp}gt;Queen{amp}lt;/span{amp}gt; {amp}lt;/bd-tarot{amp}gt; 

Если вы хотите сохранить локальную копию шаблона, вы можете скопировать ее в переменную экземпляра ( this.tmpl ).

Хотя я согласен с утверждением @ Supersharp о том, что литерал шаблона и шаблон не должны использоваться вместе, я думаю, что есть лучший способ управления HTML-шаблоном компонента, в некоторой степени смешанный между вашими подходами.

По сути, вместо того, чтобы иметь дело со строковым или шаблонным литералом, нужно определить template один раз и внедрить его оттуда при создании экземпляра каждого компонента.

 const template = document.createElement('template'); template.innerHTML = ` {amp}lt;h1 class="tarot-title"{amp}gt; {amp}lt;slot name="title"{amp}gt;NEED TITLE{amp}lt;/slot{amp}gt; {amp}lt;/h1{amp}gt; {amp}lt;img src="${this.imageurl}" alt="Как штамповать шаблон в автономных пользовательских элементов с Vanilla JS?"{amp}gt; {amp}lt;p{amp}gt; {amp}lt;slot name="subtitle"{amp}gt;NEED A SUBTITLE{amp}lt;/slot{amp}gt; {amp}lt;/p{amp}gt; `; customElements.define('bd-tarot', class extends HTMLElement { constructor() { super(); this.attachShadow({ mode: 'open' }) .appendChild(template.content.cloneNode(true)); } })(); 

Я уже писал об этом и упомянул также мою собственную библиотеку, которая объединяет большинство вышеперечисленных шаблонов в несколько API.