Vue style 屬性 scoped 原理詳解

Vue 樣式屬性 scoped 原理詳解

講講 vue 中 scoped 屬性的實現原理以及由此產生的特殊情況,然後引出樣式的權重這一概念。

(一)什麼是 scoped

當 style 標籤有 scoped 屬性時,它的 CSS 只作用於當前組件中的元素。通過該屬性,可以使組件之間的樣式互不污染,實現樣式的模塊化。

(二)scoped 原理

主要通過使用 PostCSS 來實現以下轉換:

<style scoped>
	.example {
 		 color: red;
	}
</style>

<template>
  	<div class="example">hi</div>
</template>

轉換結果:

<style>
	.example[data-v-7668812d] {
  		color: red;
	}
</style>

<template>
  	<div class="example" data-v-7668812d>hi</div>
</template>

通過給 dom 增加一個動態屬性,然後 css 選擇器也額外添加對應的屬性來選擇該 dom ,達到該樣式只作用於含有該屬性的 dom,實現組件樣式的模塊化。

(三)特殊用法

scoped 這個屬性就是專門用於實現樣式的模塊化的,使用這個屬性意味着樣式不能經過外部或者全局的調整,在使用之初就應該規劃好。

但有時候我們可能需要引入第三方組件,修改他的樣式又不想去除 scoped 造成組件之間的樣式污染,所以纔有了下面的特殊用法。

scoped 穿透(深度作用選擇器)

如果你希望 scoped 樣式中的一個選擇器能夠作用得“更深”,例如影響子組件,你可以使用 >>> 操作符:

<style scoped>
	.外層 >>> .第三方組件 { /* ... */ }
</style>

上述代碼將會編譯成:

.外層[data-v-7668812d] .第三方組件 { /* ... */ }

通過 >>> 可以使得在使用scoped屬性的情況下,穿透scoped,修改其他組件的值。

實現原理其實就是加權重(後面細講)

順帶一提,>>> 功能由 vue-loader 提供。 vue-loader 專門用於解析 vue 文件,提取每個語言塊(html、script、style),如有必要會通過其它 loader 處理,最後將他們組裝成一個 CommonJS 模塊,module.exports 出一個 Vue.js 組件對象。

(四)權重選擇器

CSS權重指的是樣式的優先級,有兩條或多條樣式作用於一個元素,權重高的那條樣式對元素起作用,權重相同的,後寫的樣式會覆蓋前面寫的樣式。

權重等級

  1. !important,加在樣式屬性值後,權重值爲 10000
  2. 內聯樣式,如:style=””,權重值爲1000
  3. ID選擇器,如:#content,權重值爲100
  4. 類,僞類和屬性選擇器,如: .content、:hover、[data-v-7668812d] 權重值爲10
  5. 標籤選擇器和僞元素選擇器,如:div、p、:before 權重值爲1
  6. 通用選擇器(*)、子選擇器(>)、相鄰選擇器(+)、同胞選擇器(~)、權重值爲0

相同權重下:內嵌樣式 > 內部樣式表 > 外聯樣式表

我們可以通過改變權重修改樣式,scoped 實質就是添加了屬性選擇器增加了10的權重,我們只要超過他就可以了。

如 vue-loader 提供的 >>> 實質就是爲第三方組件增加了外層屬性的類,並且該類也帶有屬性選擇器,相當於增加了20的權重。

那麼我們可以爲組件增加一個命名空間,防止變量污染,然後在當前命名空間下添加選擇器增加權重達到修改樣式的目的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章