vue中elementUI樣式無法修改的問題

xiazeqiang2018發表於2018-07-24

最近在開發中發現了修改elementUI樣式的時候,新增了scoped的元件無法修改的樣式,去掉scoped就可以了。這裡我們就先看一下scoped這個屬性的作用以及原理。

一:scoped的作用和原理

  • scoped的作用:當 <style> 標籤有 scoped 屬性時,它的 CSS 只作用於當前元件中的元素。這類似於 Shadow DOM 中的樣式封裝。它有一些注意事項,但不需要任何 polyfill。它通過使用 PostCSS 來實現以下轉換:
<style scoped>
.example {
  color: red;
}
</style>

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

轉換成

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

<template>
  <div class="example" data-v-f3f3eg9>hi</div>
</template>
  • scoped的原理:從上面程式碼中,我們可以看到,在編譯後多了個自定義屬性data-XXXXXXXXXX,這是個隨機生成的屬性。

二:解決方法
這裡我們先看一下為什麼無法修改樣式,elementUI的樣式是定義在全域性中,我們使用scoped時,區域性樣式會被全域性樣式所覆蓋(vue預設全域性樣式覆蓋區域性樣式)。那麼,我們可以通過如下方法來解決:
1:將樣式定義到全域性中
可以在一個元件中同時使用有作用域和無作用域的樣式(或者在主頁面定義樣式):

<style>
/* 全域性樣式 */
</style>

<style scoped>
/* 本地樣式 */
</style>

這裡我們就要增加權重來解決樣式覆蓋問題,此時我們可以給父級定義一個類名或者Id來增加名稱空間,達到不影響元件樣式的目的。

.aritle-page{ //你的名稱空間
    .el-tag { //element-ui 元素
      margin-right: 0px;
    }
}

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

<style scoped>
.a >>> .b { /* ... */ }
</style>

上述程式碼將會編譯成:

.a[data-v-f3f3eg9] .b { /* ... */ }

有些像 Sass 之類的前處理器無法正確解析 >>>。這種情況下你可以使用 /deep/ 操作符取而代之——這是一個 >>> 的別名,同樣可以正常工作。
寫法為:父元件cssName+ /deep/+第三方庫需要更改的cssName
例如 .parentCssName /deep/ .libCssName{}

 #table-role /deep/ .el-table__empty-block{
  height: 570px;
  overflow: auto;
}

四:動態生成的內容
通過 v-html 建立的 DOM 內容不受作用域內的樣式影響,但是你仍然可以通過深度作用選擇器來為他們設定樣式。

五:注意事項

  1. CSS 作用域不能代替 class。考慮到瀏覽器渲染各種 CSS 選擇器的方式,當 p { color: red } 設定了作用域時 (即與特性選擇器組合使用時) 會慢很多倍。如果你使用 class 或者 id 取而代之,比如 .example { color: red },效能影響就會消除。你可以在這塊試驗田中測試它們的不同。
  2. 在遞迴元件中小心使用後代選擇器! 對選擇器 .a .b 中的 CSS 規則來說,如果匹配 .a 的元素包含一個遞迴子元件,則所有的子元件中的 .b 都將被這個規則匹配。

相關文章