首頁 >web前端 >Vue.js >Vue3學習之深度剖析CSS Modules與Scope

Vue3學習之深度剖析CSS Modules與Scope

青灯夜游
青灯夜游轉載
2023-01-11 20:34:442386瀏覽

Vue3學習之深度剖析CSS Modules與Scope

Css Modules 是透過將標籤類別名稱加裝成獨一無二的類別名,例如.class 轉換成.class_abc_123,類似於symbol,獨一無二的鍵名

Css Scope 是透過為元素增加一個自訂屬性,這個屬性加上獨一無二的編號,而實現作用域隔離。

原則

CSS Modules

#CSS Modules實作CSS模組化的原理就是根據我們在config檔中定義的類別名稱命名規則為類別產生一個獨特的命名,從而實現作用域的隔離。 【相關推薦:vuejs影片教學web前端開發

  • #轉換前
  • ##
    <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[&#39;name-img&#39;]} />
              <span class={style[&#39;name-text&#39;]}>{row.name}</span>
            </span>
          );
        },
##轉換後

標籤.name-img 被轉換成_name_img_6hlfj_11等

Scoped CSS

# 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>
應用

CSS Modules

關於應用,這裡只針對介紹Vue3版本內的使用問題

在Vue3 中,CSS Modules,在

c9ccee2e6ea535a969eb3f532ad9fe89

上增加module 屬性,即a6167d77ee734aaef6dcd2aa69de7b33a6167d77ee734aaef6dcd2aa69de7b33
程式碼區塊會被編譯為CSS Modules 並且將產生的CSS 類別作為$style 物件的鍵暴露給元件,可以直接在模板中使用$style。而對於如8784e2fd63a27a4a8fec0995a8e86d19 具名CSS Modules,編譯後產生的CSS 類別作為content 物件的鍵暴露給元件,即module 屬性值什麼,就暴露什麼物件。

useCssModule模組名稱使用

<script setup>
import { useCssModule } from &#39;vue&#39;

// 不传递参数,获取<style module>代码块编译后的css类对象
const style = useCssModule()
console.log(style.success)  // 获取到的是success类名经过 hash 计算后的类名
    
// 传递参数content,获取<style module="content">代码块编译后的css类对象
const contentStyle = useCssModule(&#39;content&#39;)
</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元件內應用

#對於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[&#39;name-img&#39;]} />
          <span class={style[&#39;name-text&#39;]}>{row.name}</span>
        </span>
      );
    },

例如render函數

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

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

:global選擇器

在Scope或Module中使用global時

:global()允許括號中宣告的選擇器命中全域,即其類別名稱不會經過規則封裝,因此不受作用域的限制。

實際專案中,當我們希望修改所使用元件庫的預設樣式時,在使用CSS Modules方案的情況下,就可以透過:global()來修改其預設樣式,

但是要注意最好外面有一層類別封裝,否則可能會影響全域樣式

:deep深度作用選擇器

深度作用選擇器使得父元件的樣式可以滲透到子元件,其原理是使用後代選擇器。

/* 转化前 */
<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樣式是全域起效的。

需要在vue.config.js中額外配置Vue Loader預設支持,無需額外配置透過根據配置的類別命名規則,為元素生成獨一無二的類別名稱來實現作用域隔離透過給元素自訂hash屬性,再使用屬性選擇器選取元素來實現作用域隔離
CSS Modules #Scoped CSS

在style標籤中宣告module在style標籤中宣告scoped

###支援匯入其他module的樣式,支援樣式組合######/####### #####透過:global()來解除作用域的隔離,使樣式在全域生效######1. 可以定義全域樣式,使樣式不受作用域限制;2. 可以透過深度作用選擇器命中子元件,從而控制子元件的樣式###############(學習影片分享:###vuejs入門教學###、###程式設計基礎影片### )###

以上是Vue3學習之深度剖析CSS Modules與Scope的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.cn。如有侵權,請聯絡admin@php.cn刪除