您可以和不能从Web组件中挤出的内容

这不是教程或完整的综述,而是汇编组件库后的热血笔记。 一切都从平常的日常故事开始:有一个遗留代码,您需要将pipmochek和小棍子固定在遗留上,您不能一次重写任何内容,也不能用手触摸此处; 不要以防万一,以防万一,而事实上,为什么您不随便使用最好的Vanilla JS框架并开始编写,就像您的祖父遗赠的那样?

但是,由于预计工作量会非常引人注目,因此出于某种原因,没有人会想到用裸露的JS编写所有内容这一想法。 我们去看一下工具,并从中选择不会使我们的组件的消费者感到恐惧的工具。

工具


尽管我已经破坏了整个部分,但是这里需要说些什么。 首先,Web组件立即变得毫无争议:当创造力的结果是组件库,并且您无法拖动一个大型怪物la Angular时,它会完全完全模块化,那么剩下的就是您根本不需要拖动库代码,并在现代浏览器中“像那样”工作。 Web组件本身仍然是令人惊叹的Vanilla JS框架,仅解决了一些模块化问题。 用自己的双手还需要写很多东西-您需要标准化的包装器,并且希望每个组件的样板都最少。

这样的包装器并不多,甚至足够成熟以用于严肃的产品Hybrids, LitElement, Stencil。 他们都以相同的方式处理相同的事情,不同之处在于小事情。 Hybrids试图变得时髦和无类,Stencil变得时髦并且像反应,LitElement似乎都没有努力。 根据从微不足道的琐事中选择的结果,输出仍然是LitElement-OOPshniki从Hybrids转向鼻子,从非业余者转向-从Stencil转向,其中JSX通常觉得重复了并非最无可争辩的想法。

战斗?


在文档中讨论您可以做什么并没有那么有趣,因此我将继续主要讨论您不能做什么:他们通常不会在文档中写这些。

模式


在模板方面,LitElement使用lit-html,这非常简单:

const template = html` <div attr=${a} .property=${b} ?booleanAttr=${c} @click=${handleClick} ></div> `; 

这不是html,但您需要在一个符号中牢记三个构造-“。”,“?”和“ @”。 其他所有内容都是html。 关于JSX,带有它的className和其他名称,它与JS / TS代码相比更好一些,并且在法律上是分开的。 但是,顺便说一下,第一个“不可能”是从这里开始的-绑定任何不可行的东西,只能绑定属性和属性的值以及文本内容。 当然,在带标签的模板文字中,没有魔术,并且以一定数量的变态为代价,您可以在运行时放一个字符串,并在其上附加lit-html绑定器,但这实际上是用手进入渲染的,并且同样成功,您可以收集行并将其发送在innerHTML中。 通常,这都是通过模板的组成以及将复杂的组件分解为更简单的组件来完成的。 样板很小-几乎没有模板绑定,因为它只是一个变量,要创建一个组件,您需要五行“额外”的行。

组成部分


组件唯一(但很重要)的问题是,为了将组件与子代渲染图完全“混合”,在父模板的某个位置,您需要Shadow DOM。 当然,默认情况下它包含在LitElement中,总的来说似乎还不错。 但是,与css模块类似,影子DOM当前在样式方面存在一个大问题:要隔离样式,它必须完全隔离,但是这样会减少整个层叠。 根本不可能从外部进入孤立的样式。 通常(几乎)什么都没有。

例如,这极大地干扰了滚动不同主题的组件的能力。 影子DOM所能做的就是将所有样式选项打包到组件内部,或者尝试使主题完全依赖于CSS变量-这是“几乎”可以用来抽动孤立样式的方法。 但是有必要按字面意义为任何合理的样式提供变量,而且很有可能还会添加更多变量。

幸运的是,只需在组件中禁用LitElement中的Shadow DOM。 不幸的是,这也会禁用通过<slot>在模板的正确位置定位元素子元素的功能。 幸运的是,稍微变了一点,您可以同时获得第一个和第二个:为此,您需要在每个必要的插槽上放置一个影子根即可,并且除了<slot>之外,其中没有任何内容。 因此,组件的样式将是开放的,并且将出现插槽。 我想举一个简单的例子,但是不幸的是,用于操作插槽的代码始终无法奏效-非常有兴趣的人可以在这里阅读此问题。 我的灵感来自那里。

嗯,还值得一提的是,在可预见的将来,浏览器支持和polyfills :: part和::主题很可能会退出,并且影子DOM最终将成为每个人都在等待多年的解决方案-因此它与外界隔离可扩展/可变的。 但是到目前为止,这还不存在。

部署


在这一点上,不再写关于“不可能的事”的文章,因为所有事情都可以被进一步处理-点亮的库以ES模块的形式存在,因此没有任何问题,它们可以以任何方式以任何方式被拾取(即使使用可以处理模块本身的裸露浏览器) ) 对于IE和当前的Edge,您需要连接Web组件的polyfill,对于模块,如果要直接从浏览器中将其提起,则需要一些减轻浏览器导入负担的工具,例如es-module-shims。 好吧,还是打捆机。

连接到应用程序中的Web组件简单易用,您可以在html中开始使用它们,并在代码中提取其方法和属性。 您可以在这里看到所有这些都可以很好地附加到另一个库或框架上(反应很好,但是平均而言一切都很好)。 我们坚持使用AngularJS,并且一切都很陈旧:ng-prop允许您将某些内容传输到组件,而ng-on则允许您侦听事件。

总结


如果您需要构建组件UI并将其固定在您绝对不希望使用的组件上(旧版代码,不时髦的可怕框架以及其他不良地方),则Web组件可以很好地解决问题。 使用它们管理的主要“成熟”库很小,没有模块化和布局方面的严重技术问题,您可以直接使用它。 您选择哪种类型的库-即使不是那么重要,目前它们之间的差异也很小。 具体来说,我们采用的LitElement并没有给我们带来任何额外的问题,而是在所有情况下均以预期的方式工作。

Source: https://habr.com/ru/post/zh-CN467403/


All Articles