1. 程式人生 > 程式設計 >Vue3新特性之在Composition API中使用CSS Modules

Vue3新特性之在Composition API中使用CSS Modules

在 Vue 3 Composition API 最近的一次 beta 升級中,無論是 Vue 3 本 3 庫 vue-next,還是面向 Vue 2 過渡用的 @vue/composition-api 庫中,都同步更新了一個 useCSSModule 函式 -- 用來在使用了 Composition API 的 Vue 例項中,支援 CSS Modules 語法。

首先來看看什麼是 CSS Modules:

CSS Modules

CSS Modules 是一種 CSS 的模組化和組合系統。vue-loader 整合 CSS Modules,可以作為模擬 scoped CSS 的替代方案。

啟用 CSS Modules

如果是使用 vue cli 建立的專案,應該已經預設開啟了這一特性;如果專案中需要手動開啟,按如下設定:

// webpack.config.js
{
 module: {
  rules: [
   // ... 其它規則省略
   {
    test: /\.css$/,use: [
     'vue-style-loader',{
      loader: 'css-loader',options: {
       // 開啟 CSS Modules
       modules: true,// 自定義生成的類名
       localIdentName: '[local]_[hash:base64:8]'
      }
     }
    ]
   }
  ]
 }
}

或者與其它前處理器一起使用:

// webpack.config.js -> module.rules
{
 test: /\.scss$/,use: [
  'vue-style-loader',{
   loader: 'css-loader',options: { modules: true }
  },'sass-loader'
 ]
}

然後在元件中的 <style> 上新增 module 特性:

<style module>
.red {
 color: red;
}
.bold {
 font-weight: bold;
}
</style>

在元件中訪問 CSS Modules

在 <style> 上新增 module 後,一個叫做 $style 的計算屬性就會被自動注入元件。

<template>
 <div>
  <p :class="$style.red">
   hello red!
  </p>
 </div>
</template>

因為這是一個計算屬性,所以也支援 :class 的物件/陣列語法:

<template>
 <div>
  <p :class="{ [$style.red]: isRed }">
   Am I red?
  </p>
  <p :class="[$style.red,$style.bold]">
   Red and bold
  </p>
 </div>
</template>

也可以通過 JavaScript 訪問:

<script>
export default {
 created () {
  console.log(this.$style.red)
 }
}
</script>

Vue 2.x 傳統用法

在 Options API 元件中:

<template>
 <span :class="$style.span1">hello 111 - {{ text }}</span>
</template>

<script>
export default {
 props: {
  text: {
   type: String,default: ''
  }
 }
};
</script>

<style lang="scss" module>
.span1 {
 color: red;
 font-size: 50px;
}
</style>

對於 JSX 元件,由於其沒辦法用 scoped style,所以 CSS Modules 是個很好的選擇:

<script>
export default {
 props: {
  text: {
   type: String,default: ''
  }
 },render(h) {
  return <span class={this.$style.span1}>hello 222 - {this.text}</span>;
 }
};
</script>

<style lang="scss" module>
.span1 {
 color: blue;
 font-size: 40px;
}
</style>

Vue 3.x 中的 useCSSModule

引入 useCSSModule 函式後,在 Composition API 元件中使用 CSS Modules 就有了標準方案:

<template>
 <span :class="$style.span1">hello 333 - {{ text }}</span>
</template>

<script>
import { useCSSModule } from '@vue/composition-api';

export default {
 props: {
  text: {
   type: String,setup(props,context) {
  const $style = useCSSModule();
  return {
   $style
  };
 }
};
</script>

<style lang="scss" module>
.span1 {
 color: green;
 font-size: 30px;
}
</style>

其原始碼實現也是非常之簡單,基本就是取出 this.$style 而已:

export const useCSSModule = (name = '$style'): Record<string,string> => {
 const instance = getCurrentInstance()
 if (!instance) {
  __DEV__ && warn(`useCSSModule must be called inside setup()`)
  return EMPTY_OBJ
 }

 const mod = (instance as any)[name]
 if (!mod) {
  __DEV__ &&
   warn(`Current instance does not have CSS module named "${name}".`)
  return EMPTY_OBJ
 }

 return mod as Record<string,string>
}

自定義 CSS Modules 注入名稱

通過觀察 useCSSModule 的原始碼發現,CSS Modules 的 name 好像可以不只是 $style;確實,在 .vue 檔案中可以定義不止一個 <style module>,這可以通過設定 module 特性的值實現:

<style module="a">
 /* 注入識別符號 a */
</style>

<style module="b">
 /* 注入識別符號 b */
</style>

到此這篇關於Vue3新特性之在Composition API中使用CSS Modules的文章就介紹到這了,更多相關Vue3新特性之在Composition API中使用CSS Modules內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!