【问题标题】:Share style between several components and deduplicate it在多个组件之间共享样式并对其进行重复数据删除
【发布时间】:2021-09-06 23:51:31
【问题描述】:

我有几个带有ViewEncapsulation.None 的组件和一些应该应用于所有组件的样式。另外我希望这种样式只添加到编译包中一次。

我有 2 个想法如何做到这一点,但它们都不适合。让我们看一下带有 2 个组件 my-comp-1.component.scssmy-comp-2.component.scss 以及没有自己的角度组件的普通样式 my-comp.common.scss 的示例。

  1. 使用 scss @import 语句。它将通用脚本的代码添加到每个组件的样式中,并且在运行应用程序时添加了组件的 2 个style 标签(包括每个组件内部的通用样式)。这意味着通用样式的副本会覆盖自身,并且可以通过第二个组件的共享样式来覆盖第一个组件的样式:

  2. 在 Angular 的 styleUrls 属性中使用多个文件。现在添加了 3 个样式标签,至少它可以正常工作。但问题是main.js bundle 实际上包含 2 个共享样式副本(每个组件 1 个),并且在运行时进行了重复数据删除。是否可以将此重复数据删除移至编译时以减小捆绑包的大小?


现在需要更多代码来重现问题。

  • 应用由ng new 命令创建,并选择了scss
  • 截图代码通过npm run build编译,但生产版本具有相同的包结构

app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppComponent } from './app.component';
import { MyComp1Component } from './my-comp-1.component';
import { MyComp2Component } from './my-comp-2.component';

@NgModule({
  declarations: [
    AppComponent,
    MyComp1Component,
    MyComp2Component,
  ],
  imports: [
    BrowserModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.component.ts

import { Component, ViewEncapsulation } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `
    <my-comp-1></my-comp-1>
    <my-comp-2></my-comp-2>
  `,
  encapsulation: ViewEncapsulation.None,
})
export class AppComponent {
  title = 'angular-test';
}

my-comp-1.component.ts

import { Component, ViewEncapsulation } from '@angular/core';

@Component({
  selector: 'my-comp-1',
  template: `
    <p class="my-comp my-comp-1">My first component</p>
  `,
  styleUrls: ['./my-comp.common.scss', './my-comp-1.component.scss'],
  // styleUrls: ['./my-comp-1.component.scss'],
  encapsulation: ViewEncapsulation.None,
})
export class MyComp1Component {
  title = 'angular-test';
}

my-comp-1.component.scss

// @import 'my-comp.common.scss';

.my-comp-1 {
  font-weight: bold;
}

my-comp-2.component.ts

import { Component, ViewEncapsulation } from '@angular/core';

@Component({
  selector: 'my-comp-2',
  template: `
    <p class="my-comp my-comp-2">My second component</p>
  `,
  styleUrls: ['./my-comp.common.scss', './my-comp-2.component.scss'],
  // styleUrls: ['./my-comp-2.component.scss'],
  encapsulation: ViewEncapsulation.None,
})
export class MyComp2Component {
  title = 'angular-test';
}

my-comp-2.component.scss

// @import 'my-comp.common.scss';

.my-comp-2 {
  font-style: italic;
}

my-comp.common.scss

.my-comp {
  color: blue;
}

用 scss 完整截图@import:

带角度的完整截图styleUrls

【问题讨论】:

    标签: angular optimization sass


    【解决方案1】:

    您可以在项目的 src 文件夹中的 style.scss 中导入样式,这样在挂载组件和捆绑包时不会重复。

    【讨论】:

    • 但是它总是添加到页面中的全局样式。我希望样式与组件有关系,这样如果不使用这些组件(可能是因为延迟加载的原因),这些样式就不会加载到客户端。
    • Angular 尚无法实现。
    【解决方案2】:

    在你的 typescript 组件中使用 ViewEncapsulation 来共享样式:

    @Component({
      selector: "toolbar",
      templateUrl: "./sth.component.html",
      styleUrls: ["./sth.component.scss"],
      encapsulation: ViewEncapsulation.None,
    })
    

    【讨论】:

    • 已经在使用了。这不是我要问的问题。
    猜你喜欢
    • 1970-01-01
    • 2012-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-15
    • 2018-04-10
    • 2020-08-31
    相关资源
    最近更新 更多