摘要:一個應用是離不開與,其中充斥的整個項目中。下面我會分別對與解決方案進行說明,最后在分析它們的利弊與選擇。不過一個子組件的根節點會同時受其父組件有作用域的和子組件有作用域的的影響。但它的局限性是適用于中小項目中。
一個web應用是離不開html、css與js,其中css充斥的整個web項目中。css它有一個特定,它是全局的。這樣的特性導致的結果是,一旦你在不同的地方定義了相同的css命名,那么它們的樣式就會相互覆蓋,最終導致的style錯亂,從而影響整個網頁布局。
我相信對于每一個前端開發者都遇到過這種css樣式覆蓋的情況,值得慶幸的是,這些問題前輩都已經給出了解決方案。
在Vue中我們通過Scoped與Module來解決。下面我會分別對scoped與module解決方案進行說明,最后在分析它們的利弊與選擇。如果你還未使用過或者說對它們之間的利弊與選擇存在疑問的,相信這篇文章能夠幫你解惑。
Scoped假設我們有如下一段代碼:
index.vue
我是紅色的
GreenTitle.vue
我是綠色的
最終這屏幕上展示的是兩行紅色的文字,這就是父組件與子組件都定義了title-wrap的樣式,導致子組件的樣式被父組件所覆蓋。
遇到這種情況,可以在style標簽中添加scoped屬性
scoped作用的阻止上層的css樣式傳遞到下層,限制當前css作用域,使其只對當前組件生效。
知道了它的作用,下面我們在開深入看下它的實現。
前面的是沒有添加scoped的源碼,后面是添加了scoped的源碼。我們進行一一對比,發現前面的兩個div標簽都使用了title-wrap樣式,自然導致樣式覆蓋;而后面的兩個div標簽,第一個增加了data-v-67e6b31f的前綴,這就是父組的style中增加scoped的效果,區別與第二個div中的title-wrap樣式。
scoped的實現是借助了PostCSS實現的,一旦增加了scoped,他會將之前覆蓋的樣式轉換成下面的樣式
通過這種轉換方式,間接的改變了原有的css命名。防止上層組件樣式覆蓋下層組件樣式。
特性細心的讀者可能會發現上面的后一張源碼圖中第二個div的content中也有data-v-67e6b31f,可能會疑問,第二個content不是子組件中的css嗎?子組件中未添加scoped,為什么還會添加data-v-67e6b31f前綴?
這是scoped的一個特性,使用 scoped 后,父組件的樣式將不會滲透到子組件中。不過一個子組件的根節點會同時受其父組件有作用域的 CSS 和子組件有作用域的 CSS 的影響。這樣設計是為了讓父組件可以從布局的角度出發,調整其子組件根元素的樣式。
所以如果我們將子組件做如下修改
我是綠色的
由于父組件scoped特性,所以會影響到子組件的title-wrap,也會添加data-v-67e6b31f前綴
那么又有個疑問,增加了scoped是否就一定不能傳遞的下層組件呢?畢竟我們可能有需要個別樣式傳遞到下層的需求。別急,接著看,這個也能很方便的解決。
深度作用如果你希望scoped中的某個樣式能夠作用的更深,影響到子組件,你可以使用>>>操作符
注意看我將style中的lang="scss"去掉了,因為加了預處理器后無法正確解析>>>,這種情況可以使用/deep/代替,本質是>>>的別名
將會編譯成
.content[data-v-67e6b31f] .title-wrap { font-size: 20px; color: red; }
通過 v-html 創建的 DOM 內容不受作用域內的樣式影響,但是你仍然可以通過深度作用選擇器來為他們設置樣式Module
針對上面的覆蓋問題,還可以通過設置module來解決
我是紅色的
module的用法也很簡單,只要在style中增加module屬性即可。不同之處是它在布局中的引用,都需要添加前綴$style。因為通過module作用的style都被保存到$style對象中。我可以通過console查看它的具體引用名。
mounted() { console.log(this.$style) console.log(this.$style["title-wrap"]) }
通過觀察,發現引用名有一定的規律。都是已index開頭,后面再接著style中定義的命名,最后再接個后綴。這里的index是父組件的文件名index.vue。所以通過module作用的style將會重新命名為:文件名_原style名_不定后綴。
這么命名又有什么好處呢?我們再來看下展示的效果
當我們在瀏覽的控制臺查看Elements時,優點顯而易見。相對于scoped的方式,module的方式能夠一眼知道該元素時屬于哪個文件組件中。在大型項目中能夠幫助我們迅速定位到要查找的組件。
除了上述的快速定位,由于module會將所有的style都歸入$style中,所以我們可以很靈活的將任意的父組件樣式傳遞到任意深層的子組件中。例如,將父組件中的title-wrap通過props傳遞到子組件中
我是紅色的
我是綠色的
module還有一個特性非常不錯,它可以導出定義的變量,將變量歸入$style中,例如:
我是紅色的 {{$style.titleColor}}
更多module相關操作可以點擊查看總結
scoped與module都非常簡單、易用,那么又該如何選擇呢?
通過上面的使用對比,發現scoped不需要額外的知識,只要在style中定義scoped屬性即可,使用非常簡便。但它的局限性是適用于中小項目中。因為scoped作用的style對于我們來說不直觀,對于快速查找定位,module更加合適,同時module對于style向下傳遞的控制權也非常靈活;額外的還有變量導出等便捷功能。
所以如果你是小項目中且低成本的使用,scoped更加適合;而對大項目module更加合適,雖然有一點學習成本,但對于用更好的控制權、可觀性與定位速度來說也就不值一提。
公眾號感覺不錯的可以來一波關注,掃描下方二維碼,關注公眾號:怪談時間,及時獲取最新知識技巧與互聯網新動態。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/101384.html
摘要:一個應用是離不開與,其中充斥的整個項目中。下面我會分別對與解決方案進行說明,最后在分析它們的利弊與選擇。不過一個子組件的根節點會同時受其父組件有作用域的和子組件有作用域的的影響。但它的局限性是適用于中小項目中。 showImg(https://segmentfault.com/img/bVbnIPd?w=900&h=383); 一個web應用是離不開html、css與js,其中css充...
摘要:一個應用是離不開與,其中充斥的整個項目中。下面我會分別對與解決方案進行說明,最后在分析它們的利弊與選擇。不過一個子組件的根節點會同時受其父組件有作用域的和子組件有作用域的的影響。但它的局限性是適用于中小項目中。 showImg(https://segmentfault.com/img/bVbnIPd?w=900&h=383); 一個web應用是離不開html、css與js,其中css充...
摘要:先展示一下文件目錄結構先把相關的依賴給裝好注意一下注釋只是為了解釋,在中不能寫注釋插件加載器預編譯語法跨平臺環境用來設置命令行安裝預編譯語法的配置中的對象,用于處理目錄的對象,提高開發效率。 Foreword 之前三篇大致介紹了webpack的用法,正如這個系列標題而言 從webpack 到 vue Component,所以最后一篇文章當然是要講 component, 不對應該說是結合...
摘要:先展示一下文件目錄結構先把相關的依賴給裝好注意一下注釋只是為了解釋,在中不能寫注釋插件加載器預編譯語法跨平臺環境用來設置命令行安裝預編譯語法的配置中的對象,用于處理目錄的對象,提高開發效率。 Foreword 之前三篇大致介紹了webpack的用法,正如這個系列標題而言 從webpack 到 vue Component,所以最后一篇文章當然是要講 component, 不對應該說是結合...
摘要:修改庫組件樣式在工作中經常會碰見設計稿和庫的組件樣式不一樣,在標簽加了,就無法修改組件的樣式了,因為當前組件樣式只應用到這個組件上。 vue修改UI庫組件樣式 在工作中經常會碰見設計稿和UI庫的組件樣式不一樣,在style標簽加了scoped,就無法修改UI組件的樣式了,因為當前組件樣式只應用到這個組件上。 深度作用選擇器 如果你想修改組件的樣式就可以使用 >>> 操作符: .lan...
閱讀 1776·2021-11-11 11:02
閱讀 1679·2021-09-22 15:55
閱讀 2483·2021-09-22 15:18
閱讀 3488·2019-08-29 11:26
閱讀 3743·2019-08-26 13:43
閱讀 2646·2019-08-26 13:32
閱讀 897·2019-08-26 10:55
閱讀 965·2019-08-26 10:27