Rumah  >  Artikel  >  hujung hadapan web  >  Bagaimana untuk melaksanakan pengasingan gaya dalam Angular? Penjelasan terperinci tentang mekanisme pelaksanaan

Bagaimana untuk melaksanakan pengasingan gaya dalam Angular? Penjelasan terperinci tentang mekanisme pelaksanaan

青灯夜游
青灯夜游ke hadapan
2023-01-25 05:30:011797semak imbas

Bagaimanakah Angular melaksanakan pengasingan gaya? Artikel berikut akan membawa anda memahami mekanisme pelaksanaan pengasingan gaya Angular. Saya harap ia akan membantu anda!

Bagaimana untuk melaksanakan pengasingan gaya dalam Angular? Penjelasan terperinci tentang mekanisme pelaksanaan

sudut menggunakan komponen sebagai unit asasnya. Kami menulis komponen satu demi satu, dan kemudian menggabungkan komponen ini menjadi pokok komponen. Walau bagaimanapun, semasa proses pembangunan, selalunya perlu untuk mengatasi gaya komponen anak dalam komponen induk. Sebagai contoh, kini kita mempunyai komponen induk dan komponen anak Terdapat rentang dalam komponen anak, dan fon rentang berwarna merah.

Seperti yang ditunjukkan di bawah:

//child.componet.html
<span class="child-span">child span</span>
//child.component.scss
.child-span {
  color: red;
}

Jika sekarang, komponen induk mahu kandungan span dalam komponen anak bertukar hijau. Anda boleh menggunakan kaedah berikut

//parent.component.scss
app-child {
  ::ng-deep {
    .child-span {
      color: green;
    }
  }
}

dalam komponen induk dan gunakan kata kunci ::ng-deep yang disediakan oleh sudut untuk mengatasi gaya. [Tutorial berkaitan yang disyorkan: "tutorial sudut"]

Sekarang mari ubah suai kandungan komponen kanak-kanak dan tambahkan lapisan div di luar rentang Lagipun, pastinya bukan sahaja satu komponen dalam realiti.

//child.componet.html
<div class="child-div">
  <span class="child-span">child span</span>
</div>
//child.component.scss
.child-div {
  .child-span {
    color: red;
  }
}

Pada masa ini, kami akan mendapati bahawa kandungan span dalam komponen anak telah berubah kembali kepada merah, dan tiruan sebelumnya oleh komponen induk tidak berkuat kuasa.

::ng-deep Mengapa ia gagal? Dengan kata lain, bilakah ::ng-deep akan berkesan? Bilakah ia tamat tempoh? Tambahan pula, bagaimanakah pengasingan gaya antara komponen dan komponen dalam Angular dicapai?

pemilih css

css menyediakan pemilih elemen, pemilih id, pemilih kelas dan pemilih atribut.

Untuk isu pengasingan gaya dalam Sudut, perkara yang lebih penting ialah pemilih atribut. Dalam pemilih atribut, anda boleh memilih elemen dengan tepat dengan menambahkan sebarang atribut padanya. Contohnya,

a[target] {
    background-color:yellow;
}

Melalui pemilih di atas, kita boleh memilih semua elemen dengan atribut sasaran.

Yang satu lagi ialah pemilih keturunan.

Dalam CSS, pemilih keturunan memilih semua elemen keturunan unsur yang ditentukan. Contohnya,

[attr] span {
    color: green;
}

Pemilih ini mula-mula akan memilih elemen dengan atribut attr, dan kemudian memilih semua elemen rentang keturunan elemen ini.

Dengan pemilih atribut css dan pemilih keturunan, anda mempunyai semua alatan yang anda perlukan untuk melengkapkan pengasingan gaya komponen. Pengasingan gaya dan ::ng-deep komponen dalam sudut adalah berdasarkan sepenuhnya pada dua kandungan ini.

mekanisme pelaksanaan pengasingan gaya sudut

Kami kini kembali ke komponen sudut sebelumnya Kandungan komponen anak ialah

//child.componet.html
<span class="child-span">child span</span>
//child.component.scss
.child-span {
  color: red;
}

Kandungan komponen induk ialah

//parent.component.html
<app-child></app-child>

Selepas dua komponen di atas diproses secara sudut, kandungan html yang dihasilkan adalah seperti berikut

Bagaimana untuk melaksanakan pengasingan gaya dalam Angular? Penjelasan terperinci tentang mekanisme pelaksanaan

Seperti yang anda lihat, komponen induk mempunyai dua lagi atribut, _ngcontent-mye-c13 dan _nghost-mye-c12, manakala komponen anak mempunyai dua lagi atribut, _ngcontent-mye-c12 dan _nghost-mye-c11, dan teg span di bawah komponen anak , menambahkan atribut _nghost-mye-c11.

Untuk fail scss, selepas diproses oleh sudut, kelas .child-span dalam komponen anak menjadi .child-span[_nghost-mye-c11].

Bagaimana untuk melaksanakan pengasingan gaya dalam Angular? Penjelasan terperinci tentang mekanisme pelaksanaan

Melalui kandungan ini, kita dapat melihat bahawa pengasingan gaya sudut dicapai menggunakan pemilih atribut.

_nghost-mye-c11 Atribut ini hanya akan muncul dalam komponen anak. Kelas .child-span dalam child.component.scss telah menjadi .child-span[_nghost-mye-c11] Menurut mekanisme pemilih atribut yang dinyatakan sebelum ini, .child-span hanya akan berkuat kuasa pada kandungan komponen anak.

Jika anda turut menulis pemilih kelas .child-span di dalam komponen induk, pemilih kelas yang dijana akan menjadi .child-span[_nghost-mye-c12]. Atribut _nghost-mye-c12 tergolong dalam komponen induk, jadi kelas .child-span ini hanya akan berkuat kuasa ke atas kandungan komponen induk. Ia tidak akan menjejaskan komponen kanak-kanak, dan pengasingan gaya selesai.

::ng-deep

Kalau begitu mengapakah ::ng-deep boleh digunakan untuk menulis ganti kandungan dalam komponen anak dalam komponen induk?

//parent.component.scss
app-child {
  ::ng-deep {
    .child-span {
      color: green;
    }
  }
}

上面的内容通过angular 处理以后,生成的内容为app-child[_nghost-mye-c12] .child_span。位于::ng-deep 后面的类,去掉了自动添加的属性,这时候根据css 的后代选择器机制。app-child[_nghost-mye-c12] .child_span会选中child 组件下面的所有带有.child_span 类的标签,而且根据优先级计算,app-child[_nghost-mye-c12] .child_span 高于child 组件生成的.child_span[_nghost-mye-c11] ,于是child 组件中的样式就被覆盖掉了。

那为什么有时候::ng-deep不能够覆盖掉呢?比如,当child 组件代码如下的时候

//child.componet.html
<div class="child-div">
  <span class="child-span">child span</span>
</div>
//child.component.scss
.child-div {
  .child-span {
    color: red;
  }
}

这时候即使我们发现child 组件中span 的颜色依旧是红色。

实际上原因也不复杂,检查angular 生成的样式文件后,我们可以发现,之所以没有把覆盖掉,纯粹是因为css 选择器优先级的问题。child 组件生成的样式.child-div[_nghost-mye-c11] .child-span[_nghost-mye-c11] 优先级高于parent 组件生成的样式app-child[_nghost-mye-c12] .child。于是,我们看到的效果就是parent 组件中的::ng-deep 没有生效,一种比较快捷的做法是直接在parent 组件的样式后面加上!important。但是由于!important 权重太高的原因,并不是很推荐。歪个楼,在发现angular ::ng-deep 失效的原因之前,很遗憾,项目之前很多地方的都有这种用法。

另一个方法就是,既然是因为优先级不够,那么提高parent 组件生成的样式的优先级就可以了。 修改parent 组件的代码为

:host {
  app-child {
    ::ng-deep {
      .child-div {
        .child-span {
          color: green;
        }
      }
    }
  }
}

这时候,parent 组件生成的样式[_nghost-mye-c12] app-child[_nghost-mye-c12] .child-div .child-span 优先级高于child 组件生成的样式.child-div[_nghost-mye-c11] .child-span[_nghost-mye-c11] ,child 组件中span 的颜色也就变绿了。

这里我们使用了:host 关键字,接下来,我们简单看看它的作用。

:host

上个小结中,parent 组件生成的样式是[_nghost-mye-c12] app-child[_nghost-mye-c12] .child-div .child-span,如果去掉:host,就会发现,生成的样式变成了app-child[_nghost-mye-c12] .child-div .child-span。所以:host 关键字只是给生成的样式,加上了parent 组件属性字段而已。

那这个:host有什么用呢?

常见的作用有两个。

一个就是选择当前的组件标签,在angular 中,我们自定义的组件,比如这里的parent 组件app-parent 和child 组件app-child 最后都是会渲染到生成的html 文档上的。如果需要选中这些标签,就可以使用:host 关键字。

另一个作用还是隔离样式,将class 类写在:host 内部,这个类无论如何也是不可能泄漏到全局去的。实际上,通过前面的内容分析可以发现,不写在:host 里面,也不会泄漏到全局。但是如果出现了以下的情况

//some.component.scss
::ng-deep {
    .random-class {
        xxxx
    }
}

这个类经过angular 处理以后,最后会变为

.random-class {
    xxxx
}

random-class 将会对全局造成影响。

但是如果把它包裹在:host 内部,哪怕使用了::ng-deep 关键字,最多也只会影响到这个组件的后代元素。 所以在angular 官方文档中有下面的一段话。

Applying the ::ng-deep pseudo-class to any CSS rule completely disables view-encapsulation for that rule. Any style with ::ng-deep applied becomes a global style. In order to scope the specified style to the current component and all its descendants, be sure to include the :host selector before ::ng-deep. If the ::ng-deep combinator is used without the :host pseudo-class selector, the style can bleed into other components.

总结

我们首先介绍了css 的属性选择器和后代选择器。通过分析angular 生成的html 和css 代码,发现angular 的样式隔离功能,完全是基于这两个内容实现的。接下来,分析了::ng-deep 有时候生效,有时候有不生效的原因。最后介绍了使用:host 关键字来完全避免样式泄漏到全局。

更多编程相关知识,请访问:编程视频!!

Atas ialah kandungan terperinci Bagaimana untuk melaksanakan pengasingan gaya dalam Angular? Penjelasan terperinci tentang mekanisme pelaksanaan. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:juejin.cn. Jika ada pelanggaran, sila hubungi admin@php.cn Padam