HTML <template> 元素与 Javascript 模板文字

HTML <template> Element versus Javascript Template Literals

Mozilla 说 Web components 由三项主要技术组成:

  1. Custom elements
  2. Shadow DOM
  3. HTML templates

根据 ECMAscript 的 Template Literals,数字 3 "HTML templates" 是否必要?

看看我从 James Milner:

得到的这个例子
<!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 模板文字来设置 shadowRoot 的内部 HTML。

在此之后,他使用 querySelector 获取 shadowRoot 的内部元素,并最终将事件侦听器添加到递增和递减按钮。

如果您使用 HTML 模板而不是 ecmascript 模板文字,这对您有什么好处?

从概念上讲,我正在努力寻找一种我更喜欢 HTML 模板元素而不是 Ecmascript 模板文字的情况。

请指教

Web 组件本身的模板标签 'required'。当 HTML Imports 被推送时,它可能更有意义,允许导入和重用 HTML 片段,但此后已停止。在这里您可以导入一个模板并重新使用它。

重要的是要注意这些规范是独立设计的,也可以相互依赖地使用,这使得它们具有通用性。 HTML 标签有 Web 组件领域之外的用例;它很有用,因为它允许您定义一段标记,该标记在稍后通过 JavaScript 实例化之前不会呈现。事实上,您可以在不使用任何其他规范(自定义元素、阴影 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 模板。在某些方面,这会降低自定义元素的可移植性,因此模板文字可能更受欢迎。我没有测试过两者的性能,但我的直觉告诉我,该模板可能性能更高。

免责声明:原博客是我写的post