Web组件和共享样式



这是其中一个"我们应该对此做些什么"的问题。正如您所知,web组件应该是小型的、包含的网站应用程序。然而,有时这些需要根据它们嵌入的网站进行样式设置。


示例:"注册我们的时事通讯"-组件。这个组件有几个关键项目:

  • 输入框
  • 一个按钮
  • 也许重述一下
  • 一种在按下按钮后与您的服务对话的方法(传入电子邮件)

我们将以谷歌和YouTube为例。谷歌的配色方案是蓝色的(让我们想象一下),YouTube的配色方案则是红色的。然后,组件就会像<newsletter-signup></newsletter-signup>一样出现在你嵌入的页面上。谷歌和YouTube都有这个功能。

当组件需要继承谷歌和YouTube的风格时,问题就来了。一些不推荐使用的CSS选择器会很好,因为谷歌和YouTube的样式表可以简单地为Shadow DOM启用颜色,所以我们不必复制/粘贴样式。理论上,该组件不应该知道来自主机的任何样式,因为我们希望它继承自主机(谷歌和YouTube)。

目前,我正在使用Angular 6创建一个web组件,它有很多样式,因为它有很多元素。我正在从主机站点复制/粘贴样式、引导程序、图标等,然后根据<newsletter-signup brand="google"></newsletter-signup>设置它们的样式。因此,如果品牌是谷歌,那么颜色应该是红色。

这真的很糟糕,原因有几个:

  1. 必须在web组件和主机上更新样式
  2. 重复的代码从来都不是一个好主意
  3. 如果所有样式都是1:1复制的,则样式所需的字节数将加倍

作为一名开发人员,我将如何考虑这一点?如何在主机上创建样式,然后将其应用于web组件(称为继承)?我确信有人在Shadow DOM方面遇到了与我所经历的完全相同的问题。感谢阅读。

我意识到您不想为通用组件(选择器)编写相同类型的规则

也就是说,你想按照你的常用选择器的位置进行造型。

你可以做的事情来处理这个:

1.创建自己的逻辑css框架

在全局CSS中编写最常用的CSS规则。例如,如果您已经集成了bootstrap,并且您想要覆盖bootstrap的话,您将在app.css中编写最常见的覆盖,它覆盖bootstration。

"styles": [
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"src/styles/app.scss"
],

这个app.scss应该以您可以重写的方式编写。

  1. 将规则作为输入发送

发送自定义规则Obj并在要覆盖的元素中使用。

<newsletter [input]="customRulesObj"></newsletter>

组件.ts

customRulesObj = new CustomRulesClass();
customRulesObj.color = 'red';

通过创建一个公共类,可以在各种组件的输入中发送规则正如您所知道的,您将在哪里嵌入这个组件。

  1. 从通用组件扩展此组件

如果你太关心css,你可以从一个公共组件扩展你的组件,该组件根据需要为你提供css逻辑。

export class NewsLetterComponent extends CSSComponent implements OnInit
{

}

css组件.ts

在这个组件中,可以按主机、当前routerlink和其他多重if-else条件。您可以通过切换事例条件来定义规则,并将这些规则绑定到已扩展的组件。

web组件最大的必做事项之一是:我的主机(我嵌入web组件的页面)不应该依赖于web组件,也不应该知道web组件

这基本上意味着:我的web组件的样式不应该与主机共享。

如果我的主机决定更新样式,它应该会影响我的web组件。而不是相反。为了解决这个问题,我使用@import从主机直接在CSS文件中导入了外部样式。这里有一个例子:

import url("https://my-host.com/styles/core.css");
my-component {
//all styles goes here
}

我使用SASS完成了这项工作,但可以使用常规CSS完成。


这根本不是一个很好的解决方案,但它实现了我想要的:从主机继承样式。尽管我必须导入所有样式表,但它仍然有效。

我的解决方案有一个缺点:当我加载页面时,它会从<head>-标记我的主机内的<link>元素向样式发送请求,也会向我的import内的样式发送请求。因此,样式被加载两次。对于我们的应用程序(仅限内部使用),如果我们请求额外的约200 KB的数据也没关系。

这个问题已经存在几年了,情况已经改变了。现在,与web组件共享样式的方法是使用共享样式表的链接标记。

每个组件内部:

<link rel="stylesheet" href="https://my-host.com/styles/core.css">

参考:https://github.com/WICG/webcomponents/issues/628

最新更新