scoped的作用:
在vue組件中,為了使樣式私有化(模塊化)糠涛,不對(duì)全局造成污染,可以在 style 標(biāo)簽上添加scoped 屬性以表示它的只屬于當(dāng)下的模塊兼犯,這是一個(gè)非常好的舉措忍捡,但是為什么要慎用呢集漾?因?yàn)樵谖覀冃枰薷墓步M件(三方庫(kù)或者項(xiàng)目定制的組件)的樣式的時(shí)候,scoped 往往會(huì)造成更多的困難砸脊,需要增加額外的復(fù)雜度具篇。
scoped 實(shí)現(xiàn)樣式私有化原理
通過(guò)查看 DOM 結(jié)構(gòu)發(fā)現(xiàn):vue 通過(guò)在 DOM 結(jié)構(gòu)以及 css 樣式上加唯一不重復(fù)的標(biāo)記,以保證唯一凌埂,達(dá)到樣式私有化模塊化的目的驱显。
注意:當(dāng) <style> 標(biāo)簽有 scoped 屬性時(shí),它的 CSS 只作用于當(dāng)前組件中的元素瞳抓。
這類(lèi)似于 Shadow DOM 中的樣式封裝埃疫。它有一些注意事項(xiàng),但不需要任何 polyfill孩哑。它通過(guò)使用 PostCSS 來(lái)實(shí)現(xiàn)以下轉(zhuǎn)換:
轉(zhuǎn)換之前
<template>
<div class="example">hi</div>
</template>
<style scoped>
.example {
color: red;
}
</style>
轉(zhuǎn)換之后
<template>
<div class="example" data-v-f3f3eg9>hi</div>
</template>
<style>
.example[data-v-f3f3eg9] {
color: red;
}
</style>
為何慎用
從上面可以看出栓霜,添加了 scoped 屬性的組件,為了達(dá)到組件樣式模塊化横蜒,做了兩個(gè)處理:
- 給 HTML 的 DOM 節(jié)點(diǎn)加一個(gè)不重復(fù) data 屬性(形如:data-v-2311c06a )來(lái)表示他的唯一性
- 在每句 css 選擇器的末尾(編譯后生成的 css 語(yǔ)句)加一個(gè)當(dāng)前組件的 data 屬性選擇器(如[data-v-2311c06a])來(lái)私有化樣式胳蛮。
我們都知道 css 選擇器有優(yōu)先級(jí),scoped 的這一波操作丛晌,雖然實(shí)現(xiàn)了組件樣式模塊化的目的仅炊,但是每個(gè)樣式的權(quán)重加重了,這意味著若要修改這個(gè)樣式澎蛛,需要更高的權(quán)重去覆蓋這個(gè)樣式茂洒。這是增加復(fù)雜度的其中一個(gè)維度。
深度作用選擇器
如果你希望 scoped 樣式中的一個(gè)選擇器能夠作用得“更深”瓶竭,例如影響子組件,你可以使用 >>> 操作符:
<style scoped>
.a >>> .b { /* ... */ }
</style>
上述代碼將會(huì)編譯成:
.a[data-v-f3f3eg9] .b { /* ... */ }
有些像 Sass 之類(lèi)的預(yù)處理器無(wú)法正確解析 >>>
渠羞。這種情況下你可以使用 /deep/
操作符取而代之——這是一個(gè) >>>
的別名斤贰,同樣可以正常工作。
eg:
<style scoped>
.q-tab /deep/ ul {
padding-top: 20px;
}
</style>
總結(jié)scoped的渲染規(guī)則
- 給 HTML 的 DOM 節(jié)點(diǎn)加一個(gè)不重復(fù) data 屬性(形如:data-v-2311c06a)來(lái)表示他的唯一性
- 在每句 css 選擇器的末尾(編譯后的生成的 css 語(yǔ)句)加一個(gè)當(dāng)前組件的 data 屬性選擇器(如 [data-v-2311c06a] )來(lái)私有化樣式
- 如果組件內(nèi)部包含有其他組件次询,只會(huì)給其他組件的最外層標(biāo)簽加上當(dāng)前組件的data屬性:
1荧恍、當(dāng)父組件樣式為scoped,且子組件樣式也為scoped屯吊,父組件會(huì)給子組件的最外層標(biāo)簽加上
當(dāng)前組件的data屬性送巡,在父組件中只能修改子組件根標(biāo)簽的樣式,重寫(xiě)不了組件內(nèi)部的樣式盒卸,
可以使用`深度作用選擇器`骗爆。
2、當(dāng)父組件樣式為全局樣式蔽介,且子組件樣式為scoped摘投,或者煮寡,父子組件均為全局組件,
父組件內(nèi)可以修改子組件的樣式犀呼,比權(quán)重幸撕。
總結(jié):當(dāng) <style> 標(biāo)簽有 scoped 屬性時(shí),該組件的樣式是私有樣式外臂,只作用于該組件不影響其他組件(尤大大)坐儿。
推薦方案
混用本地和全局樣式
你可以在一個(gè)組件中同時(shí)使用有 scoped 和非 scoped 樣式:
<style>
/*全局樣式*/
</style>
<style scoped>
/*本地樣式*/
</style>