vue中的scoped坑點

今天在覆蓋iview組件樣式的時候發現一個問題,就是沒法覆蓋組件原有的樣式,最後在github的issue中找到了答案: 不要使用scoped屬性。因而我查找了下關於scoped的文章。css

咱們假設把這種組件叫作模塊私有組件,其餘的未加scoped的叫作模塊通常組件。經過查看DOM結構發現:vue經過在DOM結構以及css樣式上加惟一不重複的標記,以保證惟一,達到樣式私有化模塊化的目的。html

代碼以下:vue

//valChange.less(使用了嵌套規則)
#valueSlide{
	.bigSlider .ivu-slider-wrap{
		height: 6px;
	}
	.bigSlider .ivu-slider-bar {
		height: 6px;
	}
	.bigSlider .ivu-slider-button{
		width: 14px;
	    height: 14px;
	} 
}

//html部分
<style lang="less" scoped>
	@import "./valChange.less";
</style>
<div class="valid-panel">
	<div class="containerBox">
		<div id="valueSlide" v-bind:style="validStyle">
			<Slider ></Slider>
		</div>
	</div>
</div>
複製代碼

也就是咱們在style中使用scoped屬性會出現下面的狀況: HTML部分: git

HTML部分
CSS部分:
這裏寫圖片描述

從上面的字能夠看出,添加了scoped屬性的組件,爲了達到組件樣式模塊化,作了兩個處理:github

  • 給HTML的DOM節點加一個不重複data屬性(形如:data-v-19fca230)來表示他的惟一性
  • 在每句css選擇器的末尾(編譯後的生成的css語句)加一個當前組件的data屬性選擇器(如[data-v-2311c06a])來私有化樣式

那麼問題來了: 對於當前組件下調用的其餘組件,data屬性只會添加到第一層HTML中: segmentfault

這裏寫圖片描述
對於咱們想覆蓋的樣式則沒法起到做用:(在瀏覽器調試中手動添加 [data-v-19fca230] 屬性後能夠匹配)
這裏寫圖片描述

解決方案: 不使用scoped屬性,更多詳細介紹能夠參考這篇文章瀏覽器

總結一下scoped三條渲染規則:bash

  • 給HTML的DOM節點加一個不重複data屬性(形如:data-v-19fca230)來表示他的惟一性
  • 在每句css選擇器的末尾(編譯後的生成的css語句)加一個當前組件的data屬性選擇器(如[data-v-19fca230])來私有化樣式
  • 若是組件內部包含有其餘組件,只會給其餘組件的最外層標籤加上當前組件的data屬性

問題補充: 1.若是不使用scoped如何解決樣式全局污染? 推薦使用scoped推進組件私有化,文章所提到的不使用僅出如今已有UI庫的樣式覆蓋上(固然人家用了scoped 那就很難辦了)。 首先,解決組件樣式全局污染,也就是咱們在這裏不使用scoped 覆蓋了樣式,那麼咱們在其餘地方調用該組件就會被覆蓋。那麼咱們在使用組件的時候對組件給一個類名 或者其餘甄別屬性(id),覆蓋樣式就針對該類名進行重寫樣式。 其次,解決其餘樣式全局污染,若是咱們經過:less

<style lang="less">
    @import "./test.less";
</style>
複製代碼

引進樣式,那麼不使用scoped"./test.less" 中的其餘類名樣式可能會污染全局,我這裏用一個比較笨的方法處理:在模板中使用兩次<style></style> 標籤:iview

<style lang="less" scoped>
    @import "./test.less";
</style>
<style lang="less">
	//你的覆蓋樣式
</style>
複製代碼

這樣既覆蓋了樣式,其餘樣式不會被覆蓋到全局,效果代碼我就補貼上來,感興趣的同窗能夠本身試一試。(注意兩個標籤的順序)。

官網 vue-loader 中提到每一個vue模板中能夠有多個<style></style>標籤,因此上面的寫法是沒有問題的。

相關文章
相關標籤/搜索