欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue項(xiàng)目中CSS?Modules和Scoped?CSS的介紹與區(qū)別

 更新時(shí)間:2022年03月21日 11:23:28   作者:胖可丁  
在vue中我們有兩種方式可以定義css作用域,一種是scoped,另一種就是css modules,下面這篇文章主要給大家介紹了關(guān)于Vue項(xiàng)目中CSS?Modules和Scoped?CSS的相關(guān)資料,需要的朋友可以參考下

背景

在前端工程化飛速發(fā)展的時(shí)候,作為非編程語(yǔ)言的CSS在融入模塊化的浪潮時(shí)產(chǎn)生了很多問(wèn)題:

  • 無(wú)法做到樣式模塊化

組件化開發(fā)是前端模塊化的核心,但是原生CSS的思想是樣式的層疊,對(duì)于組件來(lái)說(shuō)并不友好,會(huì)造成組件樣式被覆蓋等問(wèn)題。

于是我們希望樣式是存在作用域的,即在組件的作用域內(nèi),組件樣式只對(duì)該組件生效。

  • 命名混亂

在大型項(xiàng)目中,多人合作經(jīng)常容易產(chǎn)生命名混亂的問(wèn)題,直接后果就是代碼風(fēng)格不統(tǒng)一、樣式?jīng)_突等。

  • 高重復(fù)

組件開發(fā)也意味著有很多樣式代碼是重復(fù)的,在項(xiàng)目中顯得十分冗余。

于是我們希望存在一種機(jī)制可以導(dǎo)入和導(dǎo)出CSS,做到樣式的復(fù)用。

解決CSS模塊化的方案有很多種,在Vue項(xiàng)目中,Vue Loader支持的兩種分別是Scoped CSS和CSS Modules。

Scoped CSS是Vue Loader默認(rèn)支持的,因此在Vue項(xiàng)目中可以直接使用;

CSS Modules被Vue Loader視為模擬Scoped CSS的替代方案,也提供了集成來(lái)支持,但是需要寫入一些配置。

// vue.config.js
// 使用vue-cli的話,可以直接在該文件中配置,不用暴露webpack的配置
?
module.exports = {
    css: {
        // 開啟CSS Modules
        requireModuleExtension: true;
        loaderOptions: {
            // 向loader傳遞配置選項(xiàng)
            css: {
                modules: {
                    // 自定義類命名規(guī)則
                    // 在我們的項(xiàng)目中,對(duì)類的命名是根據(jù)環(huán)境不同而改變的,開發(fā)環(huán)境中會(huì)展示該類的文件路徑方便調(diào)試,其他環(huán)境中會(huì)                      使用hash值封裝
                    localIdentName: process.env.NODE_ENV === 'development' ? '[path][name]__[local]' :                          '[hash:base62:8]',
                }
            }
        }
    }
}

需要知道的是,這兩個(gè)解決方案都不是CSS的官方規(guī)范,只是我們通過(guò)一些構(gòu)建工具,比如Webpack或者腳手架來(lái)加載對(duì)應(yīng)的Loader,從而對(duì)CSS代碼進(jìn)行一些轉(zhuǎn)換,來(lái)做到實(shí)現(xiàn)模塊化的效果。

CSS Modules

原理

CSS Modules實(shí)現(xiàn)CSS模塊化的原理就是根據(jù)我們?cè)赾onfig文件中定義的類名命名規(guī)則給類生成一個(gè)獨(dú)一無(wú)二的命名,從而實(shí)現(xiàn)作用域的隔離。

  • 轉(zhuǎn)化前
<style module>
.example {
  color: red;
}
</style>
?
<template>
  <div class="example">hi</div>
</template>
  • 轉(zhuǎn)化后
<!-- 轉(zhuǎn)化規(guī)則是自己定義的 -->
<!-- 生產(chǎn)環(huán)境中,直接用hash值封裝 -->
<style module>
._1TdbN_VT {
  color: red;
}
</style>
?
<template>
  <div class="._1TdbN_VT">hi</div>
</template>
?
<!-- 開發(fā)環(huán)境中,會(huì)顯示來(lái)源 -->
<style module>
.src-views-login-Index__example {
  color: red;
}
</style>
?
<template>
  <div class=".src-views-login-Index__example">hi</div>
</template>

規(guī)則

  • Vue項(xiàng)目中的使用

在style標(biāo)簽中需要聲明module特性:

<style module>
...
</style>

聲明module特性后,Vue Loader會(huì)生成一個(gè)$style計(jì)算屬性,向組件注入CSS Modules對(duì)象,我們可以通過(guò)使用該計(jì)算屬性在template和JS中訪問(wèn)到CSS Modules對(duì)象。

<template>
    <!-- 直接通過(guò)$style來(lái)訪問(wèn)red類,同理$style作為計(jì)算屬性也支持對(duì)象和數(shù)組語(yǔ)法 -->
  <p :class="$style.red">
    This should be red
  </p>
</template>
  • Composition:樣式的組合
.classA {
    color: green;
    background: red;
}
?
.classB {
    composes: classA;
    color: red;
}
  • 使用composes規(guī)則可以把其他類和該類的樣式組合起來(lái)

  • 要注意composes聲明的規(guī)則必須在自身規(guī)則之前;

    可以一次性組合多個(gè)class,類名之間用空格隔開,但是這些class都必須是local scoped的

  • Dependencies:通過(guò)導(dǎo)入實(shí)現(xiàn)依賴

如果需要組合其他module里的樣式,可以通過(guò)導(dǎo)入的方式:

.classC {
    composes: classA from './style.css'
}
  • 要注意當(dāng)組合了不同CSS文件中的不同類時(shí),CSS Modules是默認(rèn)這些類之間不存在先后順序的,因此導(dǎo)入時(shí)要保證這些類之間沒(méi)有規(guī)則沖突
  • 組合的類之間不能存在循環(huán)依賴
  • composes實(shí)現(xiàn)的原理就是通過(guò)loader把import的CSS文件處理成ICSS格式的中間件,導(dǎo)出一個(gè)保存了所有l(wèi)ocal類名到global類名映射的對(duì)象,實(shí)際上這也是在JS文件中直接import CSS文件的原理

:global選擇器

:global()允許括號(hào)中聲明的選擇器命中全局,即其類名不會(huì)經(jīng)過(guò)規(guī)則封裝,因此不受作用域的限制。

實(shí)際項(xiàng)目中,當(dāng)我們希望修改所使用組件庫(kù)的默認(rèn)樣式時(shí),在使用CSS Modules方案的情況下,就可以通過(guò):global()來(lái)修改其默認(rèn)樣式,但是要注意最好外面有一層類封裝,否則可能影響全局樣式。

Vue3新特性

  • 自定義module命名
<style module="login">
...
</style>

支持給module命名,可以用module名替代$style,比如<div :class="login.red"></div>。

  • 組合式API中的CSS Modules

在setup()中可以使用useCssModuleAPI來(lái)獲取module對(duì)象。

  • 在CSS中使用v-bind

支持在style中把某條rule的值和data中的一個(gè)數(shù)據(jù)綁定,比如:

.red {
    color: v-bind(color);
}

Scoped CSS

原理

Vue Loader默認(rèn)使用CSS后處理器PostCSS來(lái)實(shí)現(xiàn)Scoped CSS,原理就是給聲明了scoped的樣式中選擇器命中的元素添加一個(gè)自定義屬性,再通過(guò)屬性選擇器實(shí)現(xiàn)作用域隔離樣式的效果。

  • 轉(zhuǎn)化前
<style module>
.example {
  color: red;
}
</style>
?
<template>
  <div class="example">hi</div>
</template>
  • 轉(zhuǎn)化后
<!-- 用自定義屬性把類名封裝起來(lái)了 -->
<style>
.example[data-v-f3f3eg9] {
  color: red;
}
</style>
?
<template>
  <div class="example" data-v-f3f3eg9>hi</div>
</template>

規(guī)則

  • 一個(gè)Vue文件中可以同時(shí)存在global和scoped的樣式,即允許聲明兩個(gè)style標(biāo)簽。
<style>
/* global styles */
</style>
?
<style scoped>
/* local styles */
</style>
  • 使用Scoped CSS以后,因?yàn)闃邮骄哂辛俗饔糜?,所以父組件的樣式是不會(huì)影響到子組件的,即父組件和子組件的樣式都具有自己的作用域。

    但是對(duì)于子組件的根元素來(lái)說(shuō),其樣式還是可以受父組件控制的,使得父組件可以控制布局。

  • 注意通過(guò)v-html創(chuàng)建的DOM內(nèi)容是不受Scoped CSS控制的,如果希望修改其中的樣式,可以通過(guò)深度作用選擇器。
  • 因?yàn)镾coped CSS是通過(guò)屬性選擇器實(shí)現(xiàn)的,所以最好不要和標(biāo)簽選擇器混用,會(huì)產(chǎn)生性能問(wèn)題。

深度作用選擇器

  • 深度作用選擇器使得父組件的樣式可以滲透到子組件,其原理是使用后代選擇器。
/* 轉(zhuǎn)化前 */
<style scoped>
.a :deep(.b) {
  /* ... */
}
</style>
?
/* 轉(zhuǎn)化后 */
.a[data-v-f3f3eg9] .b {
  /* ... */
}
  • 需要注意深度作用選擇器和聲明為global樣式的區(qū)別,深度作用選擇器只是為了能讓父組件控制子組件樣式,而global樣式是全局起效的。

  • 實(shí)際項(xiàng)目中,當(dāng)我們希望修改所使用組件庫(kù)的默認(rèn)樣式時(shí),在使用Scoped CSS方案的情況下,就可以通過(guò)深度作用選擇器來(lái)修改其默認(rèn)樣式。

  • 幾種深度左右選擇器的寫法:

    • /deep/:已廢棄
    • >>>:在不使用Sass預(yù)處理器時(shí)可以使用
    • ::v-deep:使用Sass預(yù)處理器時(shí)使用

Vue3新特性

  • 深度作用選擇器

    廢棄/deep和>>>,使用:deep(.child-class)來(lái)替代::v-deep

  • :slotted()選擇器

    支持使用:slotted(selector)來(lái)控制slot中的樣式

  • :global()選擇器

    當(dāng)只有某些規(guī)則需要全局起效時(shí),允許不重復(fù)聲明一個(gè)全局作用域的style標(biāo)簽,而是使用:global(selector)來(lái)聲明為全局樣式。

二者的比較

CSS ModulesScoped CSS
需要在vue.config.js中額外配置Vue Loader默認(rèn)支持,無(wú)需額外配置
通過(guò)根據(jù)配置的類命名規(guī)則,為元素生成獨(dú)一無(wú)二的類名來(lái)實(shí)現(xiàn)作用域隔離通過(guò)給元素自定義hash屬性,再使用屬性選擇器選中元素來(lái)實(shí)現(xiàn)作用域隔離
在style標(biāo)簽中聲明module在style標(biāo)簽中聲明scoped
支持導(dǎo)入其他module的樣式,支持樣式組合/
通過(guò):global()來(lái)解除作用域的隔離,使樣式在全局生效1. 可以定義全局樣式,使樣式不受作用域約束;2. 可以通過(guò)深度作用選擇器命中子組件,從而控制子組件的樣式

總結(jié)

到此這篇關(guān)于Vue項(xiàng)目中CSS Modules和Scoped CSS的介紹與區(qū)別的文章就介紹到這了,更多相關(guān)Vue中CSS Modules和Scoped CSS內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 第一個(gè)Vue插件從封裝到發(fā)布

    第一個(gè)Vue插件從封裝到發(fā)布

    這篇文章主要為大家詳細(xì)介紹了第一個(gè)Vue插件從封裝到發(fā)布的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • 基于Vue全局組件與局部組件的區(qū)別說(shuō)明

    基于Vue全局組件與局部組件的區(qū)別說(shuō)明

    這篇文章主要介紹了基于Vue全局組件與局部組件的區(qū)別說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-08-08
  • Vue+Element UI 樹形控件整合下拉功能菜單(tree + dropdown +input)

    Vue+Element UI 樹形控件整合下拉功能菜單(tree + dropdown +input)

    這篇文章主要介紹了Vue+Element UI 樹形控件整合下拉功能菜單(tree + dropdown +input)的方法,幫助大家更好的理解和學(xué)習(xí)vue,感興趣的朋友可以了解下
    2020-08-08
  • element-ui中按需引入的實(shí)現(xiàn)

    element-ui中按需引入的實(shí)現(xiàn)

    這篇文章主要介紹了element-ui中按需引入的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • vue實(shí)現(xiàn)點(diǎn)擊選中,其他的不選中方法

    vue實(shí)現(xiàn)點(diǎn)擊選中,其他的不選中方法

    今天小編就為大家分享一篇vue實(shí)現(xiàn)點(diǎn)擊選中,其他的不選中方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09
  • 解決Vue開發(fā)中對(duì)話框被遮罩層擋住的問(wèn)題

    解決Vue開發(fā)中對(duì)話框被遮罩層擋住的問(wèn)題

    在Vue的開發(fā)中,一旦我們用到對(duì)話框,經(jīng)常出現(xiàn)的問(wèn)題是對(duì)話框被遮罩層擋住,怎么來(lái)解決這個(gè)問(wèn)題呢?下面小編給大家?guī)?lái)了Vue開發(fā)中對(duì)話框被遮罩層擋住的問(wèn)題及解決方法,一起看看吧
    2018-11-11
  • vue3中的elementPlus全局組件中文轉(zhuǎn)換方式

    vue3中的elementPlus全局組件中文轉(zhuǎn)換方式

    這篇文章主要介紹了vue3中的elementPlus全局組件中文轉(zhuǎn)換方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • Vue3中按需引入ECharts詳細(xì)步驟(一看就會(huì))

    Vue3中按需引入ECharts詳細(xì)步驟(一看就會(huì))

    新項(xiàng)目采用Vue3作為前端項(xiàng)目框架,避免不了要使用echarts,這篇文章主要給大家介紹了關(guān)于Vue3中按需引入ECharts的相關(guān)資料,需要的朋友可以參考下
    2023-09-09
  • 沒(méi)有搭建腳手架時(shí)vue組件的使用方式

    沒(méi)有搭建腳手架時(shí)vue組件的使用方式

    這篇文章主要介紹了沒(méi)有搭建腳手架時(shí)vue組件的使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • VueJs 將接口用webpack代理到本地的方法

    VueJs 將接口用webpack代理到本地的方法

    本篇文章主要介紹了VueJs 將接口用webpack代理到本地的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-11-11

最新評(píng)論