Vue中scoped工作原理以及使用情景

爲什麼要使用scoped

vue中爲了讓樣式私有化,不至於當前組件的css樣式對全局造成污染,添加了scoped屬性,但同時也要慎重的使用,因爲一旦出現問題,排查起來可能會很麻煩。

scoped工作原理

我們平時開發vue的時候可能會比較好奇,經常會看到data-v-asf23235kd33k在dom元素中出現,其實這就是scoped做的事情,比如我們一個button組件,我們定義瞭如下scoped樣式,給按鈕添加一個邊框弧度。

<template>
	<button class="button">text</button>
</template>
<style scoped>
.button {
    border-raduis: 1px;
}
</style>

這樣最終渲染出來的頁面代碼應該是這樣的

<button class="button" data-v-123lsdfasi32>
    text
</button>
.button[data-v-123lsdfasi32]{
	border-raduis: 1px;
}

可以看到這樣一來,本頁面定義爲scoped下的樣式屬性,僅可能作用於當前組件,即使該組件被引用,也不會和其他的button屬性產生衝突。

總結:

  1. 給DOM節點添加一個標誌屬性
  2. 給滲透DOM節點的樣式屬性添加一個屬性選擇器。(間接提升了樣式的權重)

對上述情況做一下補充說明,css屬性會疊加,類屬性和屬性選擇權重爲 0 0 1 0,疊加後權重變爲0 0 2 0,所以通過一個簡單的類屬性可能無法覆蓋了,需要一個id選擇器或者內聯樣式。

實際使用

在引用組件到頁面中的時候,總是會有需求說本頁面修改一下組件的樣式吧,但是由於scoped屬性產生的data-v-12jfsjjj只會作用於組件DOM元素的最外層標籤,所以父組件的樣式不會滲透到子組件中去【這裏要自行理解一下爲什麼無法滲透,不做舉例】。如果不使用scoped又怕樣式滲透到全局?可以使用滲透scoped穿透,個人理解這樣的工作原理爲沿用子組件生成的序列號,不重新生成。

.outer /deep/ .button {  // outer爲組件外層屬性樣式名稱,沒有的話也可以不加
    border-raduis: 1px;
}

注意,如果使用stylus,滲透符號爲 >>>

動態生成的DOM類名可能在scoped中也不會有作用,這個時候也可以添加/deep/來讓樣式生效。

問題回顧

在之前的項目中,有一次樣式污染導致了一個比較嚴重的後果,我的自定義的一個摺疊框,當項目一開始運行的時候不會出問題,但是項目運行一段時間之後,摺疊框的內容就都看不到了,DOM節點都是有的,樣式卻變成了

opacity: 0;

這個問題當時我通過行內樣式設置爲!important解決掉了,由於開發的是移動端,結果發現這個問題耗費了很長的時間,當時沒有細究,今天學習後發現有一個組件使用過程中定義了一個和我一樣的class屬性,但是他卻沒有把這個屬性放到<scoped>中(當然了,作爲一個公共組件組件這樣使用肯定是不合理的),直接導致了他的樣式合併到了同名的我的樣式中,導致了這個問題,希望大家引以爲戒。

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