問題
在使用element-ui時,有時候想要修改組件內的樣式,但不成功,例如
<div class="test">
<el-button>按鈕</el-button>
</div>
<style lang="less" scoped>
.test{
.el-button span{
background:red;
}
}
</style>
以上對.el-button span的樣式不生效
問題的原因
想要找到解決方案,我們先來看看不生效的原因。
1)首先,scoped是如何實現局部樣式的?
查看vu-loader文檔,根據文檔可以知道,當 <style> 標簽有 scoped 屬性時,會對組件內的元素加上一個類似於data-v-f3f3eg9的獨特標簽,組件內的樣式只會對帶有這個標簽的dom元素生效,因此加上scoped后,組件內的樣式不會影響組件外。
2)那scoped為什么對第三方子組件內的dom元素不生效?
文檔中提到

仔細閱讀這句話,也就是說采用scoped后,對組件A內采用的子組件,只會對其根元素加上組件A的獨特標簽,因此對子組件的根元素改變樣式能生效,而對非根元素是不生效的。因此上面的例子如果改為對根元素.el-button修改樣式,就會生效
<style lang="less" scoped>
.test{
.el-button{
background:red;
}
}
</style>
可以看下具體的dom元素,如圖

上圖中data-v-5752faac是當前組件test的獨特標簽(其他是父元素帶上的,這里忽略),可以看到子組件el-button的根元素帶上了此標簽,而非根元素span沒帶上,因此對span的修改是不生效的,此時如果手動在span元素上加上data-v-5752faac,會發現樣式生效
3)不僅限於第三方組件
從上面的分析來看,其實不僅限於第三方組件,任何采用到的子組件,只要是想修改子組件的非根元素都是不生效的
解決方案
- 【方案一】加上一個非scoped樣式
根據文檔可知,vue可以混用本地和全局樣式,因此對子組件的非根元素樣式修改,可以單獨放在一個非 scoped 樣式中
<style>
.test{
.el-button span{
background:red;
}
}
</style>
<style scoped>
/* 本地樣式 */
</style>
- 【方案二】采用/deep/
加上/deep/,組件的樣式可以滲透到子組件相應的元素上
<style lang="less" scoped>
.test{
/deep/ .el-button span{
background:red;
}
}
</style>
參考文檔
vu-loader文檔
