Bagaimanakah Angular melaksanakan enkapsulasi pandangan? Mari bercakap tentang tiga mod pembungkusan

青灯夜游
Lepaskan: 2022-09-28 20:09:58
ke hadapan
2859 orang telah melayarinya

SudutBagaimana untuk merangkum pandangan? Artikel berikut akan memberi anda pemahaman yang mendalam tentang tiga kaedah Enkapsulasi Sudut Saya harap ia akan membantu anda!

Bagaimanakah Angular melaksanakan enkapsulasi pandangan? Mari bercakap tentang tiga mod pembungkusan

Dalam kerja harian, apabila kita menentukan Komponen, kita mesti mempertimbangkan enkapsulasinya, iaitu Katakan sama ada anda mahu gaya yang ditakrifkan dalam komponen ini untuk digunakan hanya pada komponen ini, atau sama ada anda mahu ia digunakan secara global. Dalam Angular, gaya komponen boleh dirangkumkan dalam elemen hos komponen supaya ia tidak menjejaskan seluruh aplikasi. Penghias Komponen menyediakan pilihan pengkapsulan, yang boleh digunakan untuk mengawal cara pengkapsulan paparan digunakan pada asas setiap komponen. [Tutorial berkaitan yang disyorkan: "tutorial sudut"]

ViewEncapsulation

Terdapat tiga mod enkapsulasi dalam Angular, iaitu ViewEncapsulation.ShadowDom dan ViewEncapsulation. Ditiru, ViewEncapsulation.Tiada.

export enum ViewEncapsulation {
    /**
     * Emulates a native Shadow DOM encapsulation behavior by adding a specific attribute to the
     * component's host element and applying the same attribute to all the CSS selectors provided
     * via {@link Component#styles styles} or {@link Component#styleUrls styleUrls}.
     *
     * This is the default option.
     */
    Emulated = 0,
    /**
     * Doesn't provide any sort of CSS style encapsulation, meaning that all the styles provided
     * via {@link Component#styles styles} or {@link Component#styleUrls styleUrls} are applicable
     * to any HTML element of the application regardless of their host Component.
     */
    None = 2,
    /**
     * Uses the browser's native Shadow DOM API to encapsulate CSS styles, meaning that it creates
     * a ShadowRoot for the component's host element which is then used to encapsulate
     * all the Component's styling.
     */
    ShadowDom = 3
}
Salin selepas log masuk
  • ViewEncapsulation.Emulated: Gunakan CSS berkilauan untuk mensimulasikan tingkah laku asli.
  • ViewEncapsulation.Tiada: Gunakan CSS global tanpa sebarang enkapsulasi.
  • ViewEncapsulation.ShadowDom: Gunakan Shadow DOM v1 untuk merangkum gaya.

Jika tidak disediakan, nilai akan mendapatnya daripada CompilerOptions. Pilihan pengkompil lalai ialah ViewEncapsulation.Emulated.

Jika dasar ditetapkan kepada ViewEncapsulation.Emulated dan komponen tidak menyatakan gaya atau styleUrls, ia akan bertukar secara automatik kepada ViewEncapsulation.None.

Adakah anda menjumpai jenis enumerasi? Mengapa tiada 1? Lebih lanjut mengenai ini kemudian.

ViewEncapsulation.ShadowDom

Mengetepikan enkapsulasi ShadowDom dalam Angular, mari kita lihat dahulu apa itu ShadowDOM.

Shadow DOM

Shadow DOM membenarkan melampirkan pokok DOM tersembunyi pada pokok DOM biasa - ia bermula dengan nod akar bayang sebagai nod akar, dalam ini Di bawah nod akar, ia boleh menjadi sebarang elemen, sama seperti elemen DOM biasa.

Bagaimanakah Angular melaksanakan enkapsulasi pandangan? Mari bercakap tentang tiga mod pembungkusan

Di sini, terdapat beberapa istilah khusus Shadow DOM yang perlu kita fahami:

  • Hos bayangan: nod DOM biasa yang Shadow DOM akan dilampirkan pada nod ini.
  • Pokok bayangan: Pokok DOM di dalam Shadow DOM.
  • Sempadan bayang-bayang: tempat Shadow DOM berakhir dan DOM biasa bermula.
  • Akar bayang: Nod akar pokok Bayang.

Anda boleh memanipulasi Shadow DOM dengan cara yang sama seperti DOM biasa - seperti menambah nod anak, menetapkan sifat dan menambah gaya anda sendiri pada nod (contohnya, melalui elemen.style atribut ), atau tambah gaya pada keseluruhan Shadow DOM (seperti menambah gaya dalam elemen ). Perbezaannya ialah elemen di dalam Shadow DOM tidak akan menjejaskan elemen di luarnya (kecuali :fokus-dalam), yang memudahkan pengkapsulan.

Mari kita lihat contoh mudah.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Shadow DOM</title>
    <style>
        span{
            color: green;
        }
    </style>
</head>
<body>
    <span>我是Root</span>
    <div id="app"></div>
    <script>
        let app = document.querySelector(&#39;#app&#39;);
        let shadow1 = app.attachShadow({ mode: &#39;open&#39;});
        
        let style1 = document.createElement(&#39;style&#39;);
        style1.appendChild(document.createTextNode("span{color: red;}"));
        shadow1.appendChild(style1);

        let span1 = document.createElement(&#39;span&#39;);
        span1.textContent = &#39;I am span.&#39;;
        shadow1.appendChild(span1);
    </script>
</body>
</html>
Salin selepas log masuk

Bagaimanakah Angular melaksanakan enkapsulasi pandangan? Mari bercakap tentang tiga mod pembungkusan

Contoh di atas mentakrifkan gaya span global dan juga mentakrifkan gaya span dalam shadowDOM Ia boleh dilihat bahawa ia tidak dipengaruhi oleh satu sama lain.

Encapsulation of ShadowDOM in Angular

Setelah memahami apa itu ShadowDOM, mari kita lihat enkapsulasi ShadowDOM dalam Angular.

Angular 使用浏览器内置的 Shadow DOM API 将组件的视图包含在 ShadowRoot(用作组件的宿主元素)中,并以隔离的方式应用所提供的样式。ViewEncapsulation.ShadowDom 仅适用于内置支持 shadow DOM 的浏览器。并非所有浏览器都支持它,这就是为什么 ViewEncapsulation.Emulated 是推荐和默认模式的原因。

比如下面的这个例子,使用ViewEncapsulation.ShadowDom

@Component({
  selector: &#39;user-child&#39;,
  templateUrl: &#39;UserChild.component.html&#39;,
  styles: [`
  h3{
    color: red;
  }
  `],
  encapsulation: ViewEncapsulation.ShadowDom
})

export class UserChildComponent implements OnInit {
  ......
}
Salin selepas log masuk

Bagaimanakah Angular melaksanakan enkapsulasi pandangan? Mari bercakap tentang tiga mod pembungkusan

从运行的页面上看到,user-child组件内部被封装成了一个ShadowDOM,style也被封装在了里面,并不会对外部的样式造成影响。

ViewEncapsulation.Emulated

Angular 会修改组件的 CSS 选择器,使它们只应用于组件的视图,不影响应用程序中的其他元素(模拟 Shadow DOM 行为)。

使用模拟视图封装时,Angular 会预处理所有组件的样式,以便它们仅应用于组件的视图。在正运行的 Angular 应用程序的 DOM 中,使用模拟视图封装模式的组件所在的元素附加了一些额外的属性:

<hero-details _nghost-pmm-5>
  <h3 _ngcontent-pmm-5>Mister Fantastic</h3>
  <hero-team _ngcontent-pmm-5 _nghost-pmm-6>
    <h4 _ngcontent-pmm-6>Team</h4>
  </hero-team>
</hero-details>
Salin selepas log masuk

有两种这样的属性:

属性详情
_nghost被添加到包裹组件视图的元素中,这将是本机 Shadow DOM 封装中的 ShadowRoots。组件的宿主元素通常就是这种情况
_ngcontent被添加到组件视图中的子元素上,这些属性用于将元素与其各自模拟的 ShadowRoots(具有匹配 _nghost 属性的宿主元素)相匹配。

这些属性的确切值是 Angular 的私有实现细节。它们是自动生成的,你不应在应用程序代码中引用它们。

它们以生成的组件样式为目标,这些样式会被注入到 DOM 的 部分:

[_nghost-pmm-5] {
  display: block;
  border: 1px solid black;
}

h4[_ngcontent-pmm-6] {
  background-color: white;
  border: 1px solid #777;
}
Salin selepas log masuk

这些样式经过后期处理,以便每个 CSS 选择器都使用适当的 _nghost 或 _ngcontent 属性进行扩充。这些修改后的选择器可以确保样式以隔离和有针对性的方式应用于组件的视图。

<p>child works!</p>
Salin selepas log masuk
p{
  color: green;
}
Salin selepas log masuk
@Component({
  selector: &#39;app-child&#39;,
  templateUrl: &#39;./child.component.html&#39;,
  styleUrls: [&#39;./child.component.scss&#39;],
  encapsulation: ViewEncapsulation.Emulated
})
export class ChildComponent implements OnInit {
 ......
}
Salin selepas log masuk

Bagaimanakah Angular melaksanakan enkapsulasi pandangan? Mari bercakap tentang tiga mod pembungkusan

ViewEncapsulation.Emulated 设置的结果是没有 Shadow DOM,但是通过 Angular 提供的样式包装机制来封装组件,使得组件的样式不受外部影响。虽然样式仍然是应用到整个 document,但 Angular 为 p创建了一个 [_ngcontent-oow-c11] 选择器。可以看出,我们为组件定义的样式,被 Angular 修改了。简单来说,尽管是也是全局样式,但是由于自动选择器的原因,并不会影响其他组件的样式。如果手动在其他元素上也添加这个属性,则样式也会应用到这元素上。

ViewEncapsulation.None

Angular 不应用任何形式的视图封装,这意味着为组件指定的任何样式实际上都是全局应用的,并且可以影响应用程序中存在的任何 HTML 元素。这种模式本质上与将样式包含在 HTML 本身中是一样的。

parent:

<p #caption>parent works!{{count}}</p>
<p #caption>第一个:{{count}}</p>
<span class="red-font">parent</span>
<app-child></app-child>
Salin selepas log masuk

child:

<p>child works!</p> Child
Salin selepas log masuk
p{
  color: green;
}
.red-font {
  color: red;
}
Salin selepas log masuk
@Component({
  selector: &#39;app-child&#39;,
  templateUrl: &#39;./child.component.html&#39;,
  styleUrls: [&#39;./child.component.scss&#39;],
  encapsulation: ViewEncapsulation.None
})
export class ChildComponent implements OnInit {
  ......
}
Salin selepas log masuk

Bagaimanakah Angular melaksanakan enkapsulasi pandangan? Mari bercakap tentang tiga mod pembungkusan

被废弃的Native

在Angular2中使用ViewEncapsulation.Native。

@Component({
  ...,
  encapsulation: ViewEncapsulation.Native
})
export class UserComponent {
Salin selepas log masuk

Bagaimanakah Angular melaksanakan enkapsulasi pandangan? Mari bercakap tentang tiga mod pembungkusan

ViewEncapsulation.Native 设置的结果是使用原生的 Shadow DOM 特性。Angular 会把组件按照浏览器支持的 Shadow DOM 形式渲染。其实这种就是后来的ViewEncapsulation.ShadowDom

总结

我们介绍了Angular视图封装的三种方式,各自的特点,日常工作中要根据特定的场景去选择哪种封装方式。

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

Atas ialah kandungan terperinci Bagaimanakah Angular melaksanakan enkapsulasi pandangan? Mari bercakap tentang tiga mod pembungkusan. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:juejin.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!