Web组件和共享样式

时间:2018-10-19 12:43:58

标签: css angular angular6 web-component

这是“我们应该对此做些什么”问题之一。如您所知,Web组件应该是包含在网站中的小型应用程序。但是,有时需要根据嵌入它们的网站来设置样式。


示例:“注册我们的新闻通讯”组件。该组件将包含一些关键项:

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

我们将以Google和YouTube为例。 Google的配色方案为蓝色(让我们想象一下),而YouTube的配色方案为红色。这样,该组件将在您要嵌入的页面上像<newsletter-signup></newsletter-signup>一样。Google和YouTube都具有此组件。

当组件需要继承Google和YouTube的样式时,就会出现问题。 A few deprecated CSS selectors对此非常有用,因为Google和YouTube的样式表可以仅为Shadow DOM启用颜色,因此我们不必复制/粘贴样式。从理论上讲,该组件应该对主机的样式一无所知,因为我们希望它从主机(Google和YouTube)继承。

目前,我正在使用Angular 6创建一个Web组件,该组件具有很多样式,因为它具有很多元素。我从宿主站点复制/粘贴样式,Bootstrap,图标等,然后根据<newsletter-signup brand="google"></newsletter-signup>设置样式。因此,例如,如果品牌是Google,则颜色应为红色。

这确实很糟糕,原因如下:

  1. 必须同时在Web组件和主机上更新样式
  2. 重复的代码绝不是一个好主意
  3. 如果所有样式均按1:1复制,则样式所需的字节数将增加一倍

作为开发人员,我将如何考虑这一点?如何在主机上制作样式,然后将其应用于Web组件(称为继承)?我确定有人在遇到Shadow DOM时遇到了与我完全相同的问题。感谢您的阅读。

2 个答案:

答案 0 :(得分:1)

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

即您想要在放置通用选择器的位置进行样式设置。

您可以采取的措施:

1。创建自己的逻辑CSS框架

在全局CSS中编写最常用的CSS规则。例如,如果您集成了引导程序,并且想要覆盖引导程序,则将在app.css中编写最常见的覆盖程序,以覆盖引导程序。

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

此app.scss应该以您可以覆盖的方式编写。

  1. 发送规则作为输入

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

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

component.ts

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

您可以通过创建一个通用类在各种组件的输入中发送规则 如您所知,您将组件嵌入其中。

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

如果您对CSS不太在意,则可以从通用组件扩展组件,该组件可以根据需要为您提供CSS逻辑。

export class NewsLetterComponent extends CSSComponent implements OnInit
  {


  }

css-component.ts

在此组件中,可以按照主机,当前routerlink和 其他倍数(如果存在其他条件)。 您可以通过切换案例条件来定义规则,并将这些规则绑定到扩展的组件上。

答案 1 :(得分:1)

Web组件最大的必备功能之一是:我的主机(我嵌入Web组件的页面)不应该依赖于Web组件,也不应该了解Web组件。 / p>

这基本上是什么意思:Web组件的样式不应与主机共享。

如果主持人决定更新样式,则它将影响我的Web组件。并非相反。为了解决这个问题,我使用@import从主机直接在CSS文件中导入了外部样式。这是一个示例:

import url("https://my-host.com/styles/core.css");

my-component {
    //all styles goes here
}

我使用SASS进行了此操作,但可以使用常规CSS来完成。


这根本不是一个很好的解决方案,但是它可以满足我的要求:从主机继承样式。尽管我必须导入其中的每个样式表,但仍然可以使用。

我的解决方案的缺点:加载页面时,它将向主机<link>标记内的<head>元素发送样式请求,也向内部样式发送请求。 import。因此,样式将加载两次。对于我们的应用程序(仅供内部使用),我们是否需要额外的〜200 KB数据都没有关系。