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