摘要:一封裝模式分別為原先瀏覽器行為。無任何封裝行為。以上三種模式唯一的區(qū)別在于,當(dāng)然其作用是讓組件的樣式只進(jìn)不出,換言之即組件內(nèi)的樣式不會影響到外部組件。二組件樣式組件樣式的封裝模式取決于我們對的配置,例如上面的示例。
引導(dǎo)
這是一個很簡單的話題,但是你很難在搜索到一篇比較完整的介紹它的文章,或者說單純的告訴你 ViewEncapsulation 的用法而已,這在實際項目中遠(yuǎn)遠(yuǎn)不夠的。
一、封裝模式分別為:
Native 原先瀏覽器Shadow DOM行為。
Emulated 仿真模式,通過Angular來模擬類似Shadow DOM的行為。
None 無任何封裝行為。
以上三種模式唯一的區(qū)別在于Shadow DOM,當(dāng)然其作用是讓組件的樣式只進(jìn)不出,換言之即組件內(nèi)的樣式不會影響到外部組件。有關(guān)于Shadow DOM更多的細(xì)節(jié)不在這里討論。
三者的表現(xiàn)形式
假定使用以下代碼:
@Component({ template: `test
`, styles: [`h1 { color: #f50; }`], encapsulation: ViewEncapsulation.Native })
在不同模式下產(chǎn)生的HTML&CSS風(fēng)格都不盡相同,了解這些不一樣尤為重要。它們分別為:
Native:
#shadow-root (open)test
Emulated:
test
None:
test
二、組件樣式Native & None 在內(nèi)容是一樣的,但其后者會影響至其他外部組件的 h1 元素。
組件樣式的封裝模式取決于我們對 encapsulation 的配置,例如上面的示例。當(dāng)然你可以了在 main.ts 時為所有組件統(tǒng)一設(shè)定一種行的模式,例如:
platformBrowserDynamic().bootstrapModule(AppModule, { defaultEncapsulation: ViewEncapsulation.None })
雖然三種模式都有不同的風(fēng)格,但對于一個組件而言,如果沒有一很合理的使用風(fēng)格在實際項目中會讓我們很頭疼,特別是當(dāng)項目中使用第三方組件庫(例如:ngx-bootstrap、ng-zorro-antd、material2 等)時,有時很容易受組件庫的影響抑或需要讓組件庫與業(yè)務(wù)組件樣式做一些微調(diào)時,了解一些細(xì)節(jié)非常重要。
例如一個用于渲染頁面標(biāo)頭名曰:app-header 組件,其中
Home Detail
最終生成的HTML是這樣子:
Home / Detail /
倘若你不假思索的在 app-header 組件的 styles 屬性中加上:
.ant-breadcrumb-link { font-weight: normal; }
正如你期望的那樣,可能不一定會有你想要的結(jié)果,亦或的結(jié)果可能會存在隱患。前面我說過三種模式唯一的區(qū)別在于Shadow DOM,因此說白了是兩種不同的結(jié)果。
若組件設(shè)定為 None 模式,而會生效,但只要 app-header 組件出現(xiàn)過一次在未來所有即使不再使用 app-header 組件的情況下所有的面包屑的最后一項都是是不加粗的,這便是我說的隱患。
反之,對于 Shadow 行為,它會為 nz-breadcrumb 創(chuàng)建一個額外的屬性 _ngcontent-c1 來標(biāo)識(不管是 Native、Emulated 本質(zhì)是一樣的)所設(shè)定的樣式僅限于 app-header 組件當(dāng)中。而 Angular 中即采用 :host 來表示組件自身,所以前面的CSS樣式應(yīng)該變成這樣:
:host .ant-breadcrumb-link { font-weight: normal; }
最后生成的樣式會變成這樣:
[_nghost-c1] .ant-breadcrumb-link[_ngcontent-c1] { font-weight: normal; }
我認(rèn)為我們沒有必要去理解生成的標(biāo)識符是怎么樣,只需要知道 :host 表示組件自身。
然而我們會發(fā)現(xiàn),對于第三方組件 nz-breadcrumb 組件而言,.ant-breadcrumb-link 是其組件內(nèi)部某個HTML元素的 class 而已,且它有自己的一套組件封裝規(guī)則。但我們生成的CSS中包括了一個奇怪的字符 [_ngcontent-c1],最終導(dǎo)致 app-header 組件樣式無法改變第三方組件 nz-breadcrumb 組件內(nèi)容的樣式。
這是很合理的,我的領(lǐng)地不可侵犯,Angular 組件本身即是 Web Component 標(biāo)準(zhǔn)的具體實現(xiàn)。
難道我們沒有辦法侵犯第三方組件了嗎?好在 Angular 提供了一種對未來工具更好兼容性的命令 ::ng-deep 來強制樣式允許侵入子組件。
:host ::ng-deep .ant-breadcrumb-link { font-weight: normal; }
生成的CSS會是這樣:
[_nghost-c1] .ant-breadcrumb-link { font-weight: normal; }
最終這個不加粗的效果只會在 app-header 組件內(nèi)部有效。
總結(jié)熟悉 :host、::ng-deep 組合用法對組件樣式的構(gòu)建很關(guān)鍵,Angular 組件有自己的業(yè)務(wù)邏輯、樣式、HTML模板它們是構(gòu)建一個 Web Component 的基礎(chǔ)技術(shù)核心。
希望此篇能幫助大家更好理解組件樣式。
Happy coding!
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/112743.html
摘要:如果你運用好視圖的封裝模式,會幫你解決好很多的問題。通過在組件的元數(shù)據(jù)上設(shè)置視圖封裝模式,你可以分別控制每個組件的封裝模式。 Angular2 控制視圖的封裝模式 為什么我想要分享控制視圖的封裝模式呢?主要是我們angular的項目大多數(shù)都會去引入一個UI組件,但往往因為需求和關(guān)系我們會去修改UI組件的樣式。這時,因為有些人不是很了解View encapsulation里面的屬性,往往...
摘要:技術(shù)棧概述大名,顧名思義是在年月正式發(fā)布的一套標(biāo)準(zhǔn)。小名,意為第六次變更。本項目,選擇的是的推薦配置,唯一注意的是全局變量中把的關(guān)鍵詞加上。項目結(jié)構(gòu)公共組件目錄,放一些二次封裝的等等片段式的。項目的公用樣式目錄。 技術(shù)棧概述 ES2015(ES6) 大名ES2015,顧名思義是 ECMAScript 在2015年6月正式發(fā)布的一套標(biāo)準(zhǔn)。小名ES6,意為ECMAScript第六次變更。(...
摘要:官方支持微軟出品,是的超集,是的強類型版本作為首選編程語言,使得開發(fā)腳本語言的一些問題可以更早更方便的找到。第一個組件那么我們來為我們的增加一個吧,在命令行窗口輸入。引導(dǎo)過程通過在中引導(dǎo)來啟動應(yīng)用。它們的核心就是。 第一節(jié):Angular 2.0 從0到1 (一)第二節(jié):Angular 2.0 從0到1 (二)第三節(jié):Angular 2.0 從0到1 (三) 第一章:認(rèn)識Angular...
閱讀 1452·2021-11-04 16:11
閱讀 3130·2021-10-12 10:11
閱讀 3081·2021-09-29 09:47
閱讀 1678·2021-09-22 15:40
閱讀 1092·2019-08-29 15:43
閱讀 2869·2019-08-29 13:50
閱讀 1650·2019-08-29 13:28
閱讀 2755·2019-08-29 12:54