深入理解vue中的scoped屬性
1,前言
我們知道vue為了防止css樣式污染,在每個(gè)組件中提供了
scoped屬性進(jìn)行限定css作用域;
當(dāng)<style>標(biāo)簽有 scoped 屬性時(shí),它的 CSS 只作用于當(dāng)前組件中的元素。
2,scoped原理
1, vue中的
scoped屬性,其實(shí)就是給每一個(gè)dom節(jié)點(diǎn)元素都添加了不重復(fù)的自定義屬性(如:data-v-6810cbe5);
2,然后編譯時(shí)再給樣式的末尾添加屬性選擇器進(jìn)行樣式私有化(如.btn[data-v-6810cbe5]);
如下:
轉(zhuǎn)譯前的代碼:
btn組件(使用了Vant組件庫(kù)的button組件):
<template>
<div class="copy1">
<van-button type="default">默認(rèn)按鈕</van-button>
</div>
</template>
<style scoped lang="scss">
.van-button {
background-color: red;
}
</style>瀏覽器編輯的結(jié)果如下:

可以看到,van-button類名后面添加了[data-v-03f66e5f];他的節(jié)點(diǎn)上面也自動(dòng)添加了自定義屬性 data-v-03f66e5f;
所以:就算在兩個(gè)互不相關(guān)的組件使用同樣的類名,他們的樣式也是互不影響的;
3,父子組件使用scoped的不同情況
scoped的這一操作,雖然達(dá)到了組件樣式模塊化的目的,但是會(huì)出現(xiàn)無(wú)論父組件樣式的權(quán)重有多大,也可能無(wú)法修改子組件的樣式;
下面就分四種情況具體說(shuō)明scoped的作用:
4,第一種:父組件未添加scoped,子組件未添加scoped

這是最原始的一種情況,可以看到按鈕的背景顏色為藍(lán)色。此時(shí)父組件聲明了background-color: blue;,子組件聲明了background-color: red,權(quán)重是一樣的,但是父組件style會(huì)覆蓋子組件的style;
查看Elements后會(huì)發(fā)現(xiàn),父組件的樣式文件插入位置在子組件樣式文件后面(上圖可以看出一個(gè)是第9行一個(gè)是第90行),對(duì)于權(quán)重相同的樣式,后面的會(huì)覆蓋前面,所以父組件的style生效。
5,第二種:父組件未添加scoped,子組件添加scoped
子組件:btn.vue
<template>
<div class="copy1">
<van-button type="default">默認(rèn)按鈕</van-button>
</div>
</template>
<style lang="scss" scoped>
.van-button {
background-color: red;
}
</style>
我們可以看到子組件的.van-button{background-color: red};被編譯成.van-button[data-v-03f66e5f]{background-color: red};
子組件中button樣式的權(quán)重=類選擇器(.button)+屬性選擇器([data-v-03f66e5f]),而父組件中button樣式的權(quán)重=類選擇器(.button),所以子組件樣式的權(quán)重加重了,覆蓋本來(lái)能產(chǎn)生作用的父組件樣式,導(dǎo)致按鈕背景顏色為紅色。
6,第三種:父組件添加scoped,子組件未添加scoped
父組件:
<template>
<div>
<!-- 使用子組件 -->
<div class="scoped1">
<btn></btn>
</div>
</div>
</template>
<script>
//引入
import Btn from './copy1/index.vue';
export default {
name: 'copy',
components: {
Btn,
},
};
</script>
<style lang="scss" scoped>
.scoped1 {
.van-button {
background-color: blue;
}
}
<style>子組件:btn.vue
<template>
<div class="copy1">
<van-button type="default">默認(rèn)按鈕</van-button>
</div>
</template>
<style lang="scss">
.van-button {
background-color: red;
}
</style>
我們可以看到按鈕的背景顏色為紅色,父組件style添加scoped后,所有元素都加上data-v屬性,包括子組件的根節(jié)點(diǎn),但是子組件的內(nèi)層元素就不會(huì)受影響,所以父組件的.van-button[data-v-ae1b895c] {background-color:blue;}作用不到子組件的.van-button上。
這也是直接修改element-ui或vant-ui子組件的樣式不生效的原因,就算要寫(xiě),也需要借助深度作用選擇器或樣式不寫(xiě)在scoped屬性中。
注意:
如果只修改子組件根節(jié)點(diǎn)的樣式,還是可以寫(xiě)到父組件的scoped CSS里面,因?yàn)橐粋€(gè)子組件的根節(jié)點(diǎn)會(huì)同時(shí)存在 兩個(gè)data-v屬性的,一個(gè)是父組件本來(lái)的,另一個(gè)是子組件根節(jié)點(diǎn)上面的;(見(jiàn)上圖左邊部分);所以也會(huì)影響到子組件的根節(jié)點(diǎn)元素;
7,第四種:父組件添加scoped,子組件也添加scoped
效果圖如下:

我們可以看到,子組件的根節(jié)點(diǎn)不僅有子組件的data-v屬性,還有父組件的data-v屬性。而.van-button元素依然不受父組件的影響,只擁有自己組件的data-v屬性,所以按鈕顏色依舊為紅色。
這和上面第三種的情況是一樣的;如法直接覆蓋子組件的樣式;
8,解決方案
那如果我就是想讓父組件的樣式覆蓋子組件的樣式,怎么辦呢?
1,第一種使用兩個(gè)style,一個(gè)用于私有樣式(加scoped),一個(gè)用于共有樣式。
<style lang="scss" scoped>
.van-button {
....
}
// 公共樣式
<style lang="scss" >
.van-button {
background-color: blue;
}2,深度作用選擇器
父元素使用 /deep/ 或 >>>進(jìn)行穿透
<style lang="scss" scoped>
/deep/ .scoped1 {
.van-button {
background-color: blue;
}
編譯如下:
[data-v-ae1b895c] .scoped1 .van-button {
background-color: blue;
}
}
<style>有些像 Sass 之類的預(yù)處理器無(wú)法正確解析 >>>。這種情況下你可以使用 /deep/ 或 ::v-deep 操作符取而代之——兩者都是 >>> 的別名,同樣可以正常工作。
推薦使用 /deep/ 簡(jiǎn)單方便;
9,總結(jié)
1,scoped CSS里每個(gè)樣式的權(quán)重加重了,理論上我們可以修改某一個(gè)樣式,但是卻需要更高的權(quán)重去覆蓋這個(gè)樣式;
2,無(wú)論父組件樣式的權(quán)重多大,也可能無(wú)法修改子組件的樣式,除了子組件的根節(jié)點(diǎn)。
到此這篇關(guān)于vue中的scoped屬性的文章就介紹到這了,更多相關(guān)vue scoped屬性內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解vue-cli 本地開(kāi)發(fā)mock數(shù)據(jù)使用方法
這篇文章主要介紹了詳解vue-cli 本地開(kāi)發(fā)mock數(shù)據(jù)使用方法,如果后端接口尚未開(kāi)發(fā)完成,前端開(kāi)發(fā)一般使用mock數(shù)據(jù)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-05-05
使用FileReader API創(chuàng)建Vue文件閱讀器組件
這篇文章主要介紹了使用FileReader API創(chuàng)建一個(gè)Vue的文件閱讀器組件,需要的朋友可以參考下2018-04-04
vue-cli+webpack項(xiàng)目 修改項(xiàng)目名稱的方法
下面小編就為大家分享一篇vue-cli+webpack項(xiàng)目 修改項(xiàng)目名稱的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-02-02
Vue項(xiàng)目部署到IIS后刷新報(bào)錯(cuò)404的問(wèn)題及解決方法
這篇文章主要介紹了Vue項(xiàng)目部署到IIS后,刷新報(bào)錯(cuò)404,這里需要用到URL重寫(xiě)工具?--URL?Rewrite,需要的話需要自己下載安裝,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-10-10
vue如何解決輪播圖(Swiper)第一張圖片一閃而過(guò)問(wèn)題
這篇文章主要介紹了vue如何解決輪播圖(Swiper)第一張圖片一閃而過(guò)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01
vue中使用iframe嵌入網(wǎng)頁(yè),頁(yè)面可自適應(yīng)問(wèn)題
這篇文章主要介紹了vue中使用iframe嵌入網(wǎng)頁(yè),頁(yè)面可自適應(yīng)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09
vue項(xiàng)目使用定時(shí)器每隔幾秒運(yùn)行一次某方法代碼實(shí)例
有時(shí)候在項(xiàng)目中我們經(jīng)常需要設(shè)置簡(jiǎn)單的倒計(jì)時(shí)功能,這個(gè)可以通過(guò)定時(shí)器來(lái)實(shí)現(xiàn),下面這篇文章主要給大家介紹了關(guān)于vue項(xiàng)目使用定時(shí)器每隔幾秒運(yùn)行一次某方法的相關(guān)資料,需要的朋友可以參考下2023-04-04

