天天看點

vue scoped踩坑記錄

【樣式修改失敗】前幾天開發需求,遇到一個坑,我無論怎麼修改樣式都無法完成 對公司内部的一個基礎元件樣式進行修改。經過排查,因為我在style标簽上加入了scoped屬性,于是我需要對scoped這個屬性進行研究。

scoped作用

讓.vue中的樣式不影響其他.vue元件中的樣式。

在vue元件中,為了使樣式私有化(子產品化),不對全局造成污染,在style标簽上添加scoped屬性,以表示它隻屬于當下的子產品。

vue scoped踩坑記錄

如圖所示,我添加了scoped屬性,dom和 css選擇器後面都會添加一個不重複的data屬性,如圖中的:data-v-f29e1056。

是以,scoped屬性會做以下兩件事:

  • 給HTML的DOM節點增加一個不重複的data屬性。
  • 在每句css選擇器的末尾(編譯後生成的css語句)加一個目前元件的data屬性選擇器,對樣式進行私有化。

于是我們會遇到兩種情況:

  • 在不使用scoped的元件中加入了使用了scoped的元件。
  • 在使用了scoped屬性的元件中加入了使用了scoped的元件。

在 不使用 scoped的元件中引用帶scoped屬性的元件

<template>
 <div class="son-warp">
  <son class="son">text</son>
 </div>
</template>
...
<style scoped>
 .son-warp{
  display:inline-block;
 }
 .son{
  padding: 5px 10px;
  font-size: 12px;
  border-raduis: 2px;
 }
</style>      
//father.vue
<template>
 <div class="father">
  <p class="title"></p>

  <son></son>
 </div>
</template>
...
<style>
 .father{
  width: 200px;
  margin: 0 auto;
 }
 .father .son{
  border-raduis: 5px;
 }
</style>      

最後的結果會是:

<div class="father">
 <p class="title"></p>
 <!-- son上面定義的元件 -->
 <div data-v-f29e1056 class="son-warp">
  <son data-v-f29e1056 class="son">text</son>
 </div>
</div>
/*son.vue渲染出來的css*/
.son-warp[data-v-f29e1056]{
 display:inline-block;
}
.son[data-v-f29e1056]{
 padding: 5px 10px;
 font-size: 12px;
 border-radus: 2px;
}
/*father.vue渲染出來的css*/
.father{
 width: 200px;
 margin: 0 auto;
}
.father.son{
 border-raduis: 5px;
}      

此時由于權重關系,我們隻需要調整對應的權重就可以調出我們需要的樣式。

在 使用 scoped的元件中引用帶scoped屬性的元件

在父元件的style标簽加入scoped屬性

//father.vue
<template>
 <div class="father">
  <p class="title"></p>

  <son></son>
 </div>
</template>
...
<style scoped>
 .father{
  width: 200px;
  margin: 0 auto;
 }
 .father .son{
  border-raduis: 5px;
 }
</style>      

浏覽器渲染的結果是:

<div data-v-57bc25a0 class="father">
 <p data-v-57bc25a0 class="title"></p>
 <!-- son是上面定義的元件 -->
 <div data-v-57bc25a0 data-v-f29e1056 class="son-warp">
  <son data-v-f29e1056 class="son">text</son>
 </div>
</div>
/*son.vue渲染出來的css*/
.son-warp[data-v-f29e1056]{
 display:inline-block;
}
.son[data-v-f29e1056]{
 padding: 5px 10px;
 font-size: 12px;
 border-radus: 2px;
}
/*father.vue渲染出來的css*/
.father[data-v-57bc25a0]{
 width: 200px;
 margin: 0 auto;
}
.father .son[data-v-57bc25a0]{
 border-raduis: 5px;
}      

解決方法

  1. 引入樣式
  2. 再寫一個不加scoped的style(最好同時用BEM css命名規範 等方式去限定style影響範圍)