深度解析為什么vue組件中添加scoped后某些樣式不生效?給出解決辦法


轉載自:

版權聲明:本文為CSDN博主「Ardor-Zhang」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/qq_41800366/article/details/107062781

 

參考:https://vue-loader.vuejs.org/zh/guide/scoped-css.html#%E6%B7%B7%E7%94%A8%E6%9C%AC%E5%9C%B0%E5%92%8C%E5%85%A8%E5%B1%80%E6%A0%B7%E5%BC%8F

 

1 簡述
博主近期使用 vue 時寫發現某些樣式不生效,怎么都不生效, 不過將style 中的 scoped 去掉后,居然生效了,那么出現樣式不生效的原因肯定就是 scoped 搗的鬼,在仔細研究過后得出了一些結論,包括為什么會出現這種情況和解決辦法,在此分享。

2 深度解析
為了便於展示和理解,博主在這里選擇了一父組件和一子組件,
父組件: 首先,父組件引入子組件TestScoped

<template>
  <div class="parent">
  <p>Here is parent component</p>
  <TestScoped />
  </div>
</template>
<style>
.parent {
    color: deepskyblue;
}
</style>


子組件: TestScoped

<template>
  <div class="son">
  <p>Here is son component</p>
  </div>
</template>

 

2.1 不添加 scoped
此時的HTML編譯后的結果是:

<div class="parent">
  <p>Here is parent component</p>
  <div class="son">
    <p>Here is son component</p>
  </div>
</div>

 

沒錯,是我們所理解的樣子,這時候因為在父組件中添加了如是的樣式,那么肯定子組件的Here is son component也帶有這個樣式,結果的確是這樣。

<style>
p {
  color: deepskyblue;
}
</style>


渲染后的結果。


2.2 添加 scoped
也就是在父組件的style中添加scoped

<style scoped>
.p {
  color: deepskyblue;
}
</style>

 

此時的HTML編譯后的結果是:

<div data-v-7ba5bd90 class="parent">
  <p data-v-7ba5bd90>Here is parent component</p>
  <div data-v-7ba5bd90 class="son">
    <p>Here is son component</p>
  </div>
</div>

 

此時的編譯結果也能夠理解,也就是 vue 給父組件的每一個標簽自動添加一個唯一的 attribute, 這里 注意,你會發現vue給子組件的根標簽也打上了這一個唯一的attribute, 但是子組件的其他標簽卻沒有打上。

編譯后會發現,添加的css樣式變成了如下:添加了唯一的標簽,這也就是vue scoped 實現樣式隔離的原理

p[data-v-7ba5bd90] {
  color: deepskyblue;
}


由於子組件中除根標簽以為其他都未打上父組件的唯一標簽,那么可想而知,樣式不會在子組件中生效,結果的確如此。

總結: 為什么vue組件中添加scoped后某些樣式不生效?
原因: vue的scoped為本組件的所有標簽都打上了一個唯一attribute,樣式生效時也帶上了這唯一的attribute,但是本組件應用的所有子組件,除根標簽以為其他都未打上這唯一標簽,因此樣式自然不會生效。

3 解決辦法
3.1 官方解決辦法
點擊查看官方解決辦法
vue給出的解決辦法是: 深度作用選擇器
如果你希望 scoped 樣式中的一個選擇器能夠作用得“更深”,例如影響子組件,你可以使用 >>> 操作符
有些像 Sass 之類的預處理器無法正確解析 >>>。這種情況下你可以使用 /deep/ 或 ::v-deep 操作符取而代之——兩者都是 >>> 的別名,同樣可以正常工作。

通常我們會選擇/deep/,使用方式如下,在需要子組件樣式生效的地方加上/deep/

<style scoped>
/deep/p{
  color: deepskyblue;
}
</style>


此時HTML編譯結果不會改變,只是樣式的生效方式不同了,變成了如下:

[data-v-7ba5bd90] p {
  color: deepskyblue;
}

這樣便使得css生效


3.2 博主選擇的解決辦法
博主一般不會使用/deep/,因為嫌麻煩,每一個要用的地方都得寫,因此,博主的選擇是采用兩個style,其中一個添加scoped,寫組內的樣式,另一個不添加,修改子組件的樣式

<style scoped>
p{
  color: deepskyblue;
}
</style>

<style>

</style>


相信只要你看完這篇博文,你肯定能夠完全理解為什么scoped后樣式不起作用了

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM