【问题标题】:Web components and shared stylesWeb 组件和共享样式
【发布时间】:2019-03-24 08:37:12
【问题描述】:

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


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

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

我们将使用 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> 设置它们的样式。所以如果品牌是谷歌,颜色应该是红色的,例如。

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

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

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

【问题讨论】:

    标签: css angular angular6 web-component


    【解决方案1】:

    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 数据并不重要。

    【讨论】:

    【解决方案2】:

    我知道你不想为你的通用组件(选择器)编写相同类型的规则

    即您想将样式设置为放置常用选择器的位置。

    你可以做些什么来处理这个:

    1.创建您自己的逻辑 CSS 框架

    在全局 css 中编写最常用的 CSS 规则。例如,如果您集成了 bootstrap,并且想要覆盖 bootstrap,您将在覆盖 bootstrap 的 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

    在这个组件中可以根据主机、当前路由器链接和逻辑定义 css 其他多个 if else 条件。 您可以通过 switch case 条件定义规则并将这些规则绑定到您扩展的组件。

    【讨论】:

    • 一个问题是我的主机(我包含我的 Web 组件的页面)应该共享样式。据我所知,您不能在“样式”数组中包含外部资源。我无法让它工作。我将回答我为解决其中一些问题所做的工作。
    猜你喜欢
    • 2017-07-27
    • 1970-01-01
    • 1970-01-01
    • 2021-01-31
    • 2020-12-24
    • 2021-06-06
    • 2022-07-15
    • 2018-07-29
    • 1970-01-01
    相关资源
    最近更新 更多