vue 單文件 scoped 樣式簡析

原文連接:https://ssshooter.com/2019-12...css

如何使用

<style scoped>
  .klass {
    /* style */
  }
</style>

scoped 是一個極其經常使用的 <style> 標籤屬性,使用後這一塊樣式能「神奇地」只應用在當前單文件組件,不會干擾到其父子組件。html

其原理其實很簡單,只要加上了 scoped,當前文件全部元素(不包括調用的其餘組件)都會加上一串識別碼,樣式只做用於帶碼的元素。vue

舉個簡單例子:git

<template>
  <div>
    <div></div>
    <input class="money" />
    <ChildComponent class="child" />
  </div>
</template>
<style scoped>
  .money {
    width: 90px;
  }
</style>

如上面所說,加上了 scoped 後,渲染時這個組件全部元素都會加上 data-v-xxxxx 這樣的屬性。Vue 用戶應該常常會在調試的時候見到相似這樣的結構:github

<div data-v-9bfd234a class="money"></div>

而後在 style 也會加上對應的屬性選擇器ssh

.money[data-v-9bfd234a] {
  width: 90px;
}

這樣結果就很明確了,加了 scoped 以後全部選擇器後面都加上一個屬性選擇器來限制選擇,結果就是隻應用在當前組件。this

<div data-v-9bfd234a class="child"><div class="childclass"></div></div>

若是是子組件的話就會是上面的狀況,子組件裏面的元素不會被打上 9bfd234a 標誌,可是固然,若是子組件自己也用了 scoped,固然會有另外一個 data-v- 標籤,不過隨機生成的 id 是不一樣的,因此不會互相干擾。spa

穿透方法

總有那麼一些狀況,你須要修改外部引入的子組件的樣式來配合本身的頁面。調試

若是你用了 scoped,你所寫的全部樣式都會被限制在 data-v- 屬性選擇器中。code

要解決這個最簡單的是:不要使用 scoped

實際上你要作到 scoped 這種「自治」的效果,只要在模板最外層加一個 id,而後全部樣式都寫在這個 id 之下就行了。不過這依賴 css 預處理器,否則寫起來會很麻煩。

<template>
  <div id="thispage">
    <div></div>
    <input class="money" />
    <ChildComponent class="child" />
  </div>
</template>
<style lang="scss" scoped>
  #thispage {
    .money {
      width: 90px;
    }
  }
</style>

若是你仍須要使用 scoped,能夠選擇使用 /deep/(關於 >>>,直接使用 css 也能夠用,不過一些 css 預處理器沒法處理 >>>)。

繼續使用上面的例子,若是父組件但願改變 childclass 的樣式,能夠這麼寫:

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

(雖然看着很奇葩,但確實是這麼寫)實際運行的效果是:

[data-v-9bfd234a] .childclass {
  color: red;
}

之前我會覺得 /deep/ 幹了什麼,「穿透了」父子組件。其實並非,在 scoped 的前提下 /deep/ 作的是減法,而不是加法。

換句話說 /deep/ 的效果就是讓 deep 後面的選擇器不被加上 data-v- 選擇器。

關於 scoped 的重點就這麼多,文比較短,原本打算記着就算了,可是以爲寫出來思路會更清晰,也方便之後忘了能夠查看。
本篇文章由一文多發平臺ArtiPub自動發佈

相關文章
相關標籤/搜索