沐鳴平台_vue 單文件 scoped 樣式簡析

如何使用

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

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

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

舉個簡單例子:

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

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

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

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

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

這樣結果就很明確了,加了 scoped 之後所有選擇器後面都加上一個屬性選擇器來限制選擇,結果就是只應用在當前組件。

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

如果是子組件的話就會是上面的情況,子組件裏面的元素不會被打上 9bfd234a 標誌,但是當然,如果子組件本身也用了 scoped,當然會有另一個 data-v- 標籤,不過隨機生成的 id 是不同的,所以不會互相干擾。

穿透方法

總有那麼一些情況,你需要修改外部引入的子組件的樣式來配合自己的頁面。

如果你用了 scoped,你所寫的所有樣式都會被限制在 data-v- 屬性選擇器中。

要解決這個最簡單的是:不要使用 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 的重點就這麼多,文比較短,本來打算記着就算了,但是覺得寫出來思路會更清晰,也方便以後忘了可以查看。

原文鏈接:https://ssshooter.com/

站長推薦

1.雲服務推薦: 國內主流雲服務商,各類雲產品的最新活動,優惠券領取。地址:阿里雲騰訊雲華為雲

2.廣告聯盟: 整理了目前主流的廣告聯盟平台,如果你有流量,可以作為參考選擇適合你的平台點擊進入

鏈接: http://www.fly63.com/article/detial/7214