How to stamp out template in self contained custom elements with vanilla js?

倖福魔咒の 提交于 2019-12-20 02:14:19

问题


I have a custom component that just shows a tarot card. Before the custom element I have defined a template.
In my wc's connectedCallback I attached the template itself to the shadowroot and then stamped it out by cloning it there in the shadowroot as well. I did this for 2 reasons:

  1. I want my wc component to be a self contained module; therefore I want to define my template in the same place as my custom element.
  2. It seems to be the only way to stamp out my template to make it usable without sticking it in an owner document.

    var tmpl = `
        <template id="tmpl">
        <h1 class="tarot-title"><slot name="title">NEED TITLE</slot>
        </h1>
        <img src="${this.imageurl}" alt="">
        <p><slot name="subtitle">NEED A SUBTITLE</slot></p>
    </template>`;
    
    
    
    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);
    

The problem this has created is every tarot card component I use on my page has the same template is a child, all with the same id. Since they're in the shadowroot, does it matter? Smells funny though...

My goal is simply trying to understand how the web components specs all fit together. My question is, is there a better way to do this that keeps my component code together and doesn't refer back to an owner doc? Is the template spec mostly incompatible with custom elements since html imports are not being adopted by most browser vendors?


回答1:


In a nutshell: if you use template literals then you shouldn't use <template> element.

You don't need to duplicate the template to keep the custom element and template codes together.

You can simply enclose your code in a self-executed function to be sure that the tmpl variable won't be overridden.

(function () {

var tmpl = `
    <h1 class="tarot-title"><slot name="title">NEED TITLE</slot></h1>
    <img src="${this.imageurl}" alt="">
    <p><slot name="subtitle">NEED A SUBTITLE</slot></p>`;


class BdTarot extends HTMLElement {
    constructor() {
        super()      
        this.attachShadow( { mode: 'open' } ) 
             .innerHTML = tmpl;
    }
}

customElements.define('bd-tarot', BdTarot);

})()
<bd-tarot>
<span slot="title">Queen</span>
</bd-tarot>

If you want to keep a local copy of the template, you can copy it in an instance variable (this.tmpl).



来源:https://stackoverflow.com/questions/46097077/how-to-stamp-out-template-in-self-contained-custom-elements-with-vanilla-js

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!