Элемент HTML <template>против литералов шаблонов Javascript - PullRequest
0 голосов
/ 15 ноября 2018

Mozilla сообщает Веб-компоненты состоят из трех основных технологий:

  1. Пользовательские элементы
  2. Shadow DOM
  3. HTML-шаблоны

Является ли номер 3 "HTML-шаблонами", даже необходимыми в свете шаблонных литералов ECMAscript ?

Посмотрите на этот пример, полученный от Джеймс Милнер :

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Web Component</title>
    <script type="text/javascript">
    // We define an ES6 class that extends HTMLElement
    class CounterElement extends HTMLElement{
            constructor() {
                    super();
                    // Initialise the counter value
                    this.counter = 0;

                    // We attach an open shadow root to the custom element
                    const shadowRoot= this.attachShadow({mode: 'open'});

                    // We define some inline styles using a template string
                    const styles=`
                            :host {
                                    position: relative;
                                    font-family: sans-serif;
                            }

                            #counter-increment, #counter-decrement {
                                    width: 60px;
                                    height: 30px;
                                    margin: 20px;
                                    background: none;
                                    border: 1px solid black;
                            }

                            #counter-value {
                                    font-weight: bold;
                            }
                    `;

                    // We provide the shadow root with some HTML
                    shadowRoot.innerHTML = `
                            <style>${styles}</style>
                            <h3>Counter</h3>
                            <slot name='counter-content'>Button</slot>
                            <button id='counter-increment'> - </button>
                            <span id='counter-value'> 0 </span>
                            <button id='counter-decrement'> + </button>
                    `;

                    // We can query the shadow root for internal elements
                    // in this case the button
                    this.incrementButton = this.shadowRoot.querySelector('#counter-increment');
                    this.decrementButton = this.shadowRoot.querySelector('#counter-decrement');
                    this.counterValue = this.shadowRoot.querySelector('#counter-value');

                    // We can bind an event which references one of the class methods
                    this.incrementButton.addEventListener("click", this.decrement.bind(this));
                    this.decrementButton.addEventListener("click", this.increment.bind(this));

            }
            increment() {
                    this.counter++
                    this.invalidate();
            }
            decrement() {
                    this.counter--
                    this.invalidate();
            }
            // Call when the counter changes value
            invalidate() {
                    this.counterValue.innerHTML = this.counter;
            }
    }
    // This is where the actual element is defined for use in the DOM
    customElements.define('counter-element', CounterElement);
    </script>
</head>
<body>
    <counter-element></counter-element>
</body>
</html>

Обратите внимание, что он не использует шаблон HTML, а вместо этого использует литерал шаблона ecmascript для установки innerHTMLof shadowRoot.

После этого он использует querySelector для получения внутренних элементов shadowRoot и в конечном итоге добавляет прослушиватели событий к кнопкам увеличения и уменьшения.

Если вы должны использовать шаблон HTML, вместо литерала шаблона ecmascript, что это дает вам?

Концептуально, я изо всех сил пытаюсь найти ситуацию, где я предпочел бы элемент шаблона HTML над литералом шаблона Ecmascript.

Пожалуйста, сообщите.

1 Ответ

0 голосов
/ 15 ноября 2018

Тег шаблона не является обязательным для веб-компонентов как таковых.Вероятно, это имело больше смысла, когда HTML Imports выдвигался, позволяя импортировать и повторно использовать фрагменты HTML, но с тех пор это прекратилось.Здесь вы могли бы импортировать шаблон и использовать его повторно.

Важно отметить, что спецификации разработаны как автономные и могут использоваться независимо друг от друга, что делает их универсальными.HTML-тег имеет варианты использования за пределами области веб-компонентов;это полезно, потому что позволяет вам определить фрагмент разметки, который не будет отображаться до тех пор, пока не будет создан экземпляр с помощью JavaScript позже.Действительно, вы можете использовать шаблоны без использования каких-либо других спецификаций (Custom Elements, Shadow DOM и т. Д.).

Тег шаблона, безусловно, может использоваться в сочетании с другими спецификациями.Например, мы могли бы использовать его в показанном примере, чтобы сделать код менее императивным и более сфокусированным на разметку, например:

 <template id="counterTemplate">
   <style>
         :host {
             position: relative;
             font-family: sans-serif;
         }

         #counter-increment, #counter-decrement {
             width: 60px;
             height: 30px;
             margin: 20px;
             background: none;
             border: 1px solid black;
          }

         #counter-value {
             font-weight: bold;
         }
   </style>
   <h3>Counter</h3>
   <slot name='counter-content'>Button</slot>
   <button id='counter-increment'> - </button>
   <span id='counter-value'> 0 </span>
   <button id='counter-decrement'> + </button>
</template>

, а затем использовать это позже в JavaScript, например:

   const template = document.querySelector('#counterTemplate');
   const counter = document.cloneNode(template);
   shadowRoot.appendChild(counter);

Недостатком здесь является то, что для этого потребуется, чтобы шаблон существовал в DOM до создания экземпляра, так как он полагается на наличие шаблона #counterTemplate.В некотором смысле это делает пользовательский элемент менее переносимым, поэтому литерал шаблона может быть более желательным.Я не проверял производительность обоих, но моя интуиция говорит мне, что шаблон, возможно, будет более производительным.

Отказ от ответственности : я написал оригинальное сообщение в блоге

...