相信做前端的小夥伴們肯定遇到過一個css屬性汙染全局樣式的可怕事情。
比如今天剛做好一個漂亮的頁面,明天打開電腦,樣式全變了,整個人心情都不好了。
所以今天咱們聊一聊style標籤的scoped屬性和deep深度作用選擇器。
為了解決這個問題vue提出了頁面的模塊化和模板組件化的思想。也就是把界面進行模塊化劃分,每一部分都可以作為一個獨立的模塊,然後拼成一個完整的界面。
經常使用的模塊可以進行封裝,作為通用的組件。四不是很方便
那麼scoped屬性到底是個什麼東西呢?
Scoped屬性起源
在模塊化編程下,為了模塊之間樣式不互相汙染所以vue中引入了scoped的概念。
在vue的組件中,style標籤使用scoped標籤後,定義的樣式僅作用在當前組件內部,從而避免了汙染其他組件。這樣從某種意義上就體現了模塊化的思想。
那麼vue是怎麼實現style標籤的scoped化的呢?
Scoped的原理
Vue中實現style標籤的scoped化,是通過標籤的私有化來實現的。
Vue通過在DOM節點上以及相應css樣式上添加不重複的唯一標識data-v-hash的方式,來保證DOM節點和css樣式的唯一性,從而實現模塊的私有化。
Vue的css樣式是通過PostCSS進行轉譯實現的。Scoped渲染遵循以下規則:
- 1. 將DOM節點添加唯一標識data屬性,例如data-v-12fca125,來保持唯一性
- 2. 將轉譯後的css樣式,每一條屬性結尾添加data標識([data-v-12fca125]),從而保證和DOM節點進行匹配並且私有化樣式。
- 3. 若組件內部引用其他組件,則僅給組件的最外層添加data標識。
舉個栗子
原始樣式:
編譯後的樣式:
穿透scoped樣式
實際項目中經常會組件中引用其他通用組件,那麼在父組件中直接修改子組件的樣式是不能實現子組件樣式變化的,而又不想去掉scoped屬性。
那怎麼辦呢?
所以深度作用選擇器deep就派上用場了,可以在父組件內使用/deep/來穿透scoped樣式,從而控制子組件樣式。
父組件使用deep前:
父組件使用deep後:
修改iview中組件的樣式
在使用第三方組件庫時也會經常遇到另外一個問題,即第三方組件庫進行渲染的時候僅最外層加上了data值,其內部的標籤沒有data值,那麼如果要修改組件內部的樣式,使用deep深度選擇器也不起作用了。
那怎麼辦呢?
想到了最簡單的方法,就是使用css樣式覆蓋,組件內建立一個不添加scoped屬性的style標籤。這樣就可以直接進行控制樣式了。
但是這樣又會產生一個新的問題,如果在其他模塊內也使用了此組件,組件的樣式就受到了之前模塊的影響了。
為了解決這個問題,需要在模塊內覆蓋樣式的時候,在樣式的前面加上一個組件外層div的唯一id就可以了。
例如:
.tabsContent .ivu-tabs-bar{
border-bottom: none !important;
}
小結
通過介紹vue模塊化使用scoped屬性的原理,來進行模塊的私有化,從而避免了模塊之間樣式的汙染。如果組件內使用其他組件可以通過deep深度選擇器進行控制子組件的樣式。最後介紹了修改iview中組件內部樣式的方法。
技術積累需要一點一滴,每天學一點,會發現不一樣的自己。
感興趣的朋友,請點擊關注。