将模板与HTML自定义元素一起使用

时间:2018-09-21 02:53:04

标签: javascript html5 web-component custom-element html5-template

我刚刚开始学习HTML自定义元素,并且通过阅读一系列介绍,教程和文档,我认为我对它的工作方式有很好的了解,但是我对使用正确的方式有一个哲学问题或不使用<template>标签。

自定义元素使您能够封装新功能,简化HTML文档的结构,并允许您仅插入<my-custom-element>...</my-custom-element>标记而不是<div class="my-custom-element"><span class="part1">...</span><span class="part2">...</span></div>

该元素的类定义然后设置该元素的结构和功能。然后,大量教程描述了如何使用<template>...</template><slot>...</slot>设置自定义元素的内容。然后,您必须将模板代码包含在要使用该元素的每个HTML文档中,而不是在自定义元素类的构造函数中进行设置。这是否与自定义元素以使它们更易于移植的方式帮助简化和封装功能这一事实背道而驰?还是我误解了模板在文档中的正确用法和/或位置?

从SO来看,最接近解决这个问题的地方是这个问题:

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

但是答案本质上都绕在一起,并说“不要使用<template>”,因此并不能真正消除我的困惑。

2 个答案:

答案 0 :(得分:4)

实际上,<template>元素可以通过HTML Imports从另一个文档中导入,以及定义自定义元素的Javascript代码:

<link rel="import" src="my-custom-element.html">
...
<custom-element></custom-element>

因此,不必将其包含在每个HTML文档中。 This post shows a minimal example.

HTML导入仅在Chrome和Opera中实现。如果要在Firefox和Safari中使用它们,则需要使用HTML Imports polyfill

另一方面,目前,Mozilla和Apple并不打算在各自的浏览器中本地实现HTML导入。因此,他们建议使用纯Javascript模块(使用import<script src="...">来定义自定义元素,并改为使用template literals字符串,这提供了一些优点(变量,函数),但有时更多在IDE中编写代码很复杂(因为它们使用字符串表示形式)。

也许将来standard HTML modules将被所有浏览器采用,而<template>将会成为人们关注的焦点...

请注意,如果没有HTML导入,您仍然可以使用fetch()导入一些HTML文档:

fetch( "template.html" )
    .then( stream => stream.text() )
    .then( text => 
        customElements.define( "c-e", class extends HTMLElement {
            constructor() {
                super()
                this.attachShadow( { mode: 'open'} )
                    .innerHTML = text
            }
        } )
    )

更新2019

HTML导入won't be supported natively after Chrome 73。然后,您应该使用上面列出的其他解决方案(polyfill,备用模块加载器,JS import或通过fetch直接下载)。

答案 1 :(得分:0)

免责声明:我是下面提到的rich-component库的作者。

在尝试了一些自定义元素并最近根据其提出了一个完整的项目之后,我想分享一下我的见解:

  • 任何很小的组件,都可以长成某种野兽
  • HTML的一部分可能会发展到将其保留在JS中非常不方便的程度
  • 执行使用模板,该模板一旦构建并解析,然后从该位置克隆并注入到影子根中,这是与使用文档片段而不是对活动的DOM进行变异一样的最佳实践
  • 如果应将模板内容从组件的实例更改为实例-可以使用某种数据绑定框架,并且如果对这些内容采取了极简主义的方法-处理从-template文档片段而不是对字符串或模板文字进行操作

为了不一次又一次地写同样的几十行,我准备了rich-component库,该库:

  • 标准化一些用于模板配置的API,以及所有这些“克隆模板,创建阴影,将模板的内容注入其中”重复代码行
  • 已知在提供html URL时获取html内容
  • 缓存模板,因此提取仅完成一次