Để hiểu về ViewEncapsulation trong Angular, trước tiên, chúng ta nên hiểu Shadow DOM. Bạn có thể tìm hiểu chi tiết về Shadow DOM tại đây . Nói một cách đơn giản, Shadow DOM mang đến sự đóng gói cho các phần tử HTML. Sử dụng Shadow DOM, đánh dấu, kiểu và hành vi được đặt trong phạm vi phần tử và không xung đột với các nút khác của DOM. Shadow DOM là một phần của Thành phần Web, gói gọn các kiểu và đăng nhập của phần tử.
Các thành phần góc được tạo thành từ ba điều:
- Lớp thành phần
- Bản mẫu
- Phong cách
Sự kết hợp của ba yếu tố này làm cho một thành phần Angular có thể tái sử dụng trên một ứng dụng. Về mặt lý thuyết, khi bạn tạo một thành phần, theo một cách nào đó, bạn tạo một thành phần web ( về mặt lý thuyết, Thành phần góc không phải là thành phần web ) để tận dụng Shadow DOM. Bạn cũng có thể sử dụng Angular với các trình duyệt không hỗ trợ Shadow DOM vì Angular có phần mô phỏng riêng và nó có thể mô phỏng Shadow DOM.
Để mô phỏng Shadow DOM và các kiểu đóng gói, Angular cung cấp các kiểu Xem đóng gói. Chúng là như sau:
Hãy thử hiểu nó bằng một ví dụ. Tôi đã tạo ra một thành phần, như được hiển thị dưới đây:
app.component.ts
import { Component, ViewEncapsulation } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
encapsulation: ViewEncapsulation.None
})
export class AppComponent {
title = 'parent component';
}
app.component.html app.component.css
h1 {
background: red;
color: white;
text-transform: uppercase;
text-align: center;
}
Chúng tôi đang thiết lập kiểu h1
trong CSS thành phần. Chúng tôi cũng đã tạo ra một thành phần khác:
import { Component } from '@angular/core';
@Component({
selector: 'app-child',
template: `
<h1>{{title}}</h1>
`
})
export class AppChildComponent {
title = 'child app';
}
Trong AppChildComponent
, chúng tôi cũng đang sử dụng h1
thẻ. Để hiểu các ViewEncapsulation
tùy chọn khác nhau , chúng tôi sẽ thay đổi siêu dữ liệu của AppComponent
.
Hãy bắt đầu với ViewEncapsulation.None, trong tùy chọn này:
- Không có bóng DOM.
- Phong cách không nằm trong phạm vi thành phần.
Khi bạn chạy ứng dụng, bạn sẽ thấy h1
kiểu đã áp dụng cho cả hai thành phần, mặc dù chúng tôi chỉ đặt kiểu trong AppComponent
. Điều này xảy ra bởi vì trong AppComponent
chúng tôi đã đặt thuộc tính đóng gói thành ViewEncapsulation.None
.
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
encapsulation: ViewEncapsulation.None
})
export class AppComponent {
title = 'parent component';
}
Trong trình duyệt, khi bạn kiểm tra mã nguồn, bạn sẽ thấy h1
kiểu đã được khai báo trong phần đầu của DOM.
Do đó, trong ViewEncapsulation.None
, kiểu được chuyển đến phần đầu của DOM và không nằm trong phạm vi thành phần. Không có Shadow DOM cho thành phần và kiểu thành phần có thể ảnh hưởng đến tất cả các nút trong DOM.
Tiếp theo, hãy cùng chúng tôi khám phá ViewEncapsulation.Native, trong tùy chọn này:
- Angular sẽ tạo Shadow DOM cho thành phần.
- Phong cách là phạm vi cho các thành phần.
Khi bạn chạy ứng dụng, bạn sẽ thấy h1
kiểu đã áp dụng cho cả hai thành phần, mặc dù chúng tôi chỉ đặt kiểu chỉ trong AppComponent
. Điều này xảy ra bởi vì trong AppComponent
chúng tôi đã đặt thuộc tính đóng gói thành ViewEncapsulation.Native
và chúng tôi đang sử dụng AppChildComponnet
như một đứa trẻ bên trong mẫu của AppComponent
.
import { Component, ViewEncapsulation } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
encapsulation: ViewEncapsulation.Native
})
export class AppComponent {
title = 'parent component';
}
Trong trình duyệt, khi bạn kiểm tra mã nguồn, bạn sẽ tạo Shadow DOM cho AppComponent
và kiểu được đặt trong phạm vi đó.
Do đó, trong ViewEncapsulation.Native
, Angular tạo ra Shadow DOM và kiểu được đặt trong Shadow DOM đó.
Tiếp theo, hãy cùng chúng tôi khám phá ViewEncapsulation.Emulation, trong tùy chọn này:
- Angular sẽ không tạo Shadow DOM cho thành phần.
- Phong cách sẽ được phạm vi cho các thành phần.
- Đây là giá trị mặc định cho đóng gói.
import { Component, ViewEncapsulation } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
encapsulation: ViewEncapsulation.Emulated
})
export class AppComponent {
title = 'parent component';
}
Như bạn chạy các ứng dụng, bạn sẽ thấy rằng các h1
phong cách từ AppComponent
là không áp dụng cho h1
các AppChildComponent
. Điều này là do phạm vi mô phỏng. Trong đó, phong cách chỉ nằm trong phạm vi thành phần. Trong tùy chọn này, Angular chỉ mô phỏng Shadow DOM và không tạo DOM bóng thực. Do đó, ứng dụng chạy trong trình duyệt cũng không hỗ trợ Shadow DOM và các kiểu cũng nằm trong phạm vi của thành phần.
Hãy cho chúng tôi xem làm thế nào Angular đạt được điều này. Trong trình duyệt, khi bạn kiểm tra mã nguồn, bạn sẽ tìm thấy câu trả lời.
Angular đã tạo kiểu trong phần đầu của DOM và đưa ra một id tùy ý cho thành phần. Trên cơ sở ID, kiểu chọn được đặt trong phạm vi thành phần.
Đây là ba tùy chọn ViewEncapsulation có sẵn trong Angular. Tôi hy vọng bạn tìm thấy bài viết này hữu ích. Cảm ơn vì đã đọc. Nếu bạn thích bài viết này, xin vui lòng chia sẻ nó.
Đọc nội dung rất chi là kỳ cục luôn.
VD: "...bạn sẽ thấy rằng các h1 phong cách từ..."
"h1 phong cách" có ý nghĩa gì đâu? Đọc muốn méo cả miệng, chẹo cả lưỡi @@ – LE KHAI HOAN 16:24:26 08/12/2019