您好,登錄后才能下訂單哦!
這篇文章主要講解了“Vue3的CSS Modules和Scope怎么使用”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Vue3的CSS Modules和Scope怎么使用”吧!
Css Modules 是通過對標簽類名進行加裝成一個獨一無二的類名,比如.class 轉換成.class_abc_123,類似于symbol,獨一無二的鍵名
Css Scope 是通過為元素增加一個自定義屬性,這個屬性加上獨一無二的編號,而實現作用域隔離。
CSS Modules實現CSS模塊化的原理就是根據我們在config文件中定義的類名命名規則給類生成一個獨一無二的命名,從而實現作用域的隔離。
轉化前
<style module>
.title {
font-size: 14px;
font-family: Microsoft YaHei, Microsoft YaHei-Bold;
font-weight: 700;
color: #13161b;
}
.name {
display: flex;
align-items: center;
&-img {
width: 24px;
height: 24px;
border-radius: 4px;
}
&-text {
font-size: 14px;
font-family: Microsoft YaHei, Microsoft YaHei-Regular;
font-weight: 400;
color: #13161b;
}
}
</style>
cell: (h, { col, row }) => {
// console.log(style);
return (
<span class={style.name}>
<img src={testImage} class={style['name-img']} />
<span class={style['name-text']}>{row.name}</span>
</span>
);
},
轉化后
標簽.name-img 被轉化成了_name_img_6hlfj_11等
Vue Loader默認使用CSS后處理器PostCSS來實現Scoped CSS,原理就是給聲明了scoped的樣式中選擇器命中的元素添加一個自定義屬性,再通過屬性選擇器實現作用域隔離樣式的效果。
轉化前
<template>
<div class="example">hi</div>
</template>
<style module>
.example {
color: red;
}
</style>
轉化后
<!-- 用自定義屬性把類名封裝起來了 -->
<style>
.example[data-v-f3f3eg9] {
color: red;
}
</style>
<template>
<div class="example" data-v-f3f3eg9>hi</div>
</template>
關于應用,這里只針對介紹Vue3版本內的使用問題
在 Vue3 中,CSS Modules,在 <style>
上增加 module 屬性,即<style module>
。<style module>
代碼塊會被編譯為 CSS Modules 并且將生成的 CSS 類作為 $style
對象的鍵暴露給組件,可以直接在模板中使用 $style
。而對于如 <style module="content">
具名 CSS Modules,編譯后生成的 CSS 類作為 content
對象的鍵暴露給組件,即module
屬性值什么,就暴露什么對象。
<script setup>
import { useCssModule } from 'vue'
// 不傳遞參數,獲取<style module>代碼塊編譯后的css類對象
const style = useCssModule()
console.log(style.success) // 獲取到的是success類名經過 hash 計算后的類名
// 傳遞參數content,獲取<style module="content">代碼塊編譯后的css類對象
const contentStyle = useCssModule('content')
</script>
<template>
<div>普通style red</div>
<div :class="$style.success">默認CssModule pink</div>
<div :class="style.success">默認CssModule pink</div>
<div :class="contentStyle.success">具名CssModule blue</div>
<div :class="content.success">具名CssModule blue</div>
</template>
<!-- 普通style -->
<style>
.success {
color: red;
}
</style>
<!-- 無值的css module -->
<style module>
.success {
color: pink;
}
</style>
<!-- 具名的css module -->
<style module="content">
.success {
color: blue;
}
</style>
注意,同名的CSS Module,后面的會覆蓋前面的。
針對module命名區分,主要也是應用在JSX和TSX的組件中居多
對于 JSX、TSX 組件,由于其沒辦法用 scoped style,所以 CSS Modules 是個很好的選擇:
比如在script里面寫h函數,直接使用樣式變量
cell: (h, { col, row }) => {
// console.log(style);
return (
<span class={style.name}>
<img src={testImage} class={style['name-img']} />
<span class={style['name-text']}>{row.name}</span>
</span>
);
},
比如render函數
<script>
export default {
props: {
text: {
type: String,
default: ''
}
},
render(h) {
return <span class={this.$style.span1}>hello 222 - {this.text}</span>;
}
};
</script>
<style module>
.span1 {
color: blue;
font-size: 40px;
}
</style>
在Scope或者Module中使用global時
:global()允許括號中聲明的選擇器命中全局,即其類名不會經過規則封裝,因此不受作用域的限制。
實際項目中,當我們希望修改所使用組件庫的默認樣式時,在使用CSS Modules方案的情況下,就可以通過:global()來修改其默認樣式,但是要注意最好外面有一層類封裝,否則可能影響全局樣式。
深度作用選擇器使得父組件的樣式可以滲透到子組件,其原理是使用后代選擇器。
/* 轉化前 */
<style scoped>
.a :deep(.b) {
/* ... */
}
</style>
/* 轉化后 */
.a[data-v-f3f3eg9] .b {
/* ... */
}
實際項目中,當我們希望修改所使用組件庫的默認樣式時,在使用Scoped CSS方案的情況下,就可以通過深度作用選擇器來修改其默認樣式。
幾種深度左右選擇器的寫法:
/deep/:已廢棄
'>>>':在不使用Sass預處理器時可以使用
::v-deep:使用Sass預處理器時使用
但是在Vue3中,已經作出了改進如下:
深度作用選擇器廢棄/deep和>>>,使用 :deep(.child-class) 來替代::v-deep
:slotted()選擇器支持使用:slotted(selector)來控制slot中的樣式
:global()選擇器當只有某些規則需要全局起效時,允許不重復聲明一個全局作用域的style標簽,而是使用:global(selector)來聲明為全局樣式。
深度作用選擇器deep和聲明為global樣式的區別,深度作用選擇器只是為了能讓父組件控制子組件樣式,而global樣式是全局起效的。
CSS Modules | Scoped CSS |
---|---|
需要在vue.config.js中額外配置 | Vue Loader默認支持,無需額外配置 |
通過根據配置的類命名規則,為元素生成獨一無二的類名來實現作用域隔離 | 通過給元素自定義hash屬性,再使用屬性選擇器選中元素來實現作用域隔離 |
在style標簽中聲明module | 在style標簽中聲明scoped |
支持導入其他module的樣式,支持樣式組合 | / |
通過:global()來解除作用域的隔離,使樣式在全局生效 | 1. 可以定義全局樣式,使樣式不受作用域約束;2. 可以通過深度作用選擇器命中子組件,從而控制子組件的樣式 |
感謝各位的閱讀,以上就是“Vue3的CSS Modules和Scope怎么使用”的內容了,經過本文的學習后,相信大家對Vue3的CSS Modules和Scope怎么使用這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。