跳轉到內容

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 仍然是靜態的。自定義屬性將透過內聯樣式應用到元件的根元素上,並在源值改變時進行響應式更新。

SFC CSS 功能已載入