SFC CSS功能
作用域CSS
當<style>標籤有scoped屬性時,其CSS將只應用於當前元件的元素。這類似於在Shadow DOM中找到的風格封裝。它有一些注意事項,但不需要任何polyfills。它透過使用PostCSS轉換以下內容來實現
vue
<style scoped>
.example {
color: red;
}
</style>
<template>
<div class="example">hi</div>
</template>變為以下內容
vue
<style>
.example[data-v-f3f3eg9] {
color: red;
}
</style>
<template>
<div class="example" data-v-f3f3eg9>hi</div>
</template>子元件根元素
使用 scoped 時,父元件的樣式不會洩露到子元件中。然而,子元件的根節點將同時受到父元件的 scoped CSS 和子元件本身的 scoped CSS 的影響。這是有意為之,以便父元件可以為佈局目的對子元件的根元素進行樣式化。
深度選擇器
如果您想讓 scoped 樣式中的選擇器“深度”有效,即影響子元件,可以使用 :deep() 偽類。
vue
<style scoped>
.a :deep(.b) {
/* ... */
}
</style>以上將編譯成
CSS
.a[data-v-f3f3eg9] .b {
/* ... */
}提示
使用 v-html 建立的 DOM 內容不受 scoped 樣式的影響,但您仍然可以使用深度選擇器來對它們進行樣式化。
插槽選擇器
預設情況下,scoped 樣式不會影響由 <slot/> 渲染的內容,因為它們被視為由傳入父元件擁有的。為了顯式地針對插槽內容,請使用 :slotted 偽類。
vue
<style scoped>
:slotted(div) {
color: red;
}
</style>全域性選擇器
如果您只想讓一條規則全域性應用,您可以使用 :global 偽類,而不是建立另一個 <style>(見下文)。
vue
<style scoped>
:global(.red) {
color: red;
}
</style>混合區域性和全域性樣式
您還可以在同一組件中包含 scoped 和非 scoped 樣式。
vue
<style>
/* global styles */
</style>
<style scoped>
/* local styles */
</style>Scoped 樣式提示
Scoped 樣式並不能消除對類的需求。 由於瀏覽器渲染各種 CSS 選擇器的不同方式,當 scoped(即與屬性選擇器結合時)時,
p { color: red }將變得非常慢。如果您使用類或 id(如.example { color: red }),則幾乎可以消除這種效能損失。在遞迴元件中要小心使用後代選擇器! 對於具有選擇器
.a .b的 CSS 規則,如果匹配.a的元素包含一個遞迴子元件,則該子元件中的所有.b都將匹配該規則。
CSS 模組
<style module> 標籤會被編譯為 CSS Modules,並將生成的 CSS 類作為物件暴露給元件,該物件在 $style 鍵下。
vue
<template>
<p :class="$style.red">This should be red</p>
</template>
<style module>
.red {
color: red;
}
</style>生成的類經過雜湊處理以避免衝突,從而實現了將 CSS 作用域限制為當前元件的效果。
有關更多資訊,例如 全域性異常 和 組合,請參閱 CSS Modules 規範。
自定義注入名稱
您可以透過給 module 屬性賦值來自定義注入類的物件屬性鍵。
vue
<template>
<p :class="classes.red">red</p>
</template>
<style module="classes">
.red {
color: red;
}
</style>與組合 API 一起使用
可以透過 useCssModule API 在 setup() 和 <script setup> 中訪問注入的類。對於具有自定義注入名稱的 <style module> 塊,useCssModule 接受匹配的 module 屬性值作為第一個引數。
js
import { useCssModule } from 'vue'
// inside setup() scope...
// default, returns classes for <style module>
useCssModule()
// named, returns classes for <style module="classes">
useCssModule('classes')- 示例
vue
<script setup lang="ts">
import { useCssModule } from 'vue'
const classes = useCssModule()
</script>
<template>
<p :class="classes.red">red</p>
</template>
<style module>
.red {
color: red;
}
</style>CSS 中的 v-bind()
SFC <style> 標籤支援使用 v-bind CSS 函式將 CSS 值連結到動態元件狀態。
vue
<template>
<div class="text">hello</div>
</template>
<script>
export default {
data() {
return {
color: 'red'
}
}
}
</script>
<style>
.text {
color: v-bind(color);
}
</style>該語法與 <script setup> 一起使用,並支援 JavaScript 表示式(必須用引號括起來)。
vue
<script setup>
import { ref } from 'vue'
const theme = ref({
color: 'red',
})
</script>
<template>
<p>hello</p>
</template>
<style scoped>
p {
color: v-bind('theme.color');
}
</style>實際值將被編譯成雜湊過的 CSS 自定義屬性,因此 CSS 仍然是靜態的。自定義屬性將透過內聯樣式應用到元件的根元素上,並在源值改變時進行響應式更新。