iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >Vue项目中CSS Modules和Scoped CSS的介绍与区别
  • 120
分享到

Vue项目中CSS Modules和Scoped CSS的介绍与区别

2024-04-02 19:04:59 120人浏览 安东尼
摘要

目录背景CSS Modules原理规则:global选择器vue3新特性Scoped CSS原理规则深度作用选择器Vue3新特性二者的比较总结背景 在前端工程化飞速发展的时候,作为非

背景

前端工程化飞速发展的时候,作为非编程语言的CSS在融入模块化的浪潮时产生了很多问题:

  • 无法做到样式模块化

组件化开发是前端模块化的核心,但是原生CSS的思想是样式的层叠,对于组件来说并不友好,会造成组件样式被覆盖等问题。

于是我们希望样式是存在作用域的,即在组件的作用域内,组件样式只对该组件生效。

  • 命名混乱

在大型项目中,多人合作经常容易产生命名混乱的问题,直接后果就是代码风格不统一、样式冲突等。

  • 高重复

组件开发也意味着有很多样式代码是重复的,在项目中显得十分冗余。

于是我们希望存在一种机制可以导入和导出CSS,做到样式的复用。

解决CSS模块化的方案有很多种,在Vue项目中,Vue Loader支持的两种分别是Scoped CSS和CSS Modules。

Scoped CSS是Vue Loader默认支持的,因此在Vue项目中可以直接使用;

CSS Modules被Vue Loader视为模拟Scoped CSS的替代方案,也提供了集成来支持,但是需要写入一些配置。

// vue.config.js
// 使用vue-cli的话,可以直接在该文件中配置,不用暴露webpack的配置
​
module.exports = {
    css: {
        // 开启CSS Modules
        requireModuleExtension: true;
        loaderOptions: {
            // 向loader传递配置选项
            css: {
                modules: {
                    // 自定义类命名规则
                    // 在我们的项目中,对类的命名是根据环境不同而改变的,开发环境中会展示该类的文件路径方便调试,其他环境中会                      使用hash值封装
                    localIdentName: process.env.node_ENV === 'development' ? '[path][name]__[local]' :                          '[hash:base62:8]',
                }
            }
        }
    }
}

需要知道的是,这两个解决方案都不是CSS的官方规范,只是我们通过一些构建工具,比如WEBpack或者脚手架来加载对应的Loader,从而对CSS代码进行一些转换,来做到实现模块化的效果。

CSS Modules

原理

CSS Modules实现CSS模块化的原理就是根据我们在config文件中定义的类名命名规则给类生成一个独一无二的命名,从而实现作用域的隔离。

  • 转化前
<style module>
.example {
  color: red;
}
</style>
​
<template>
  <div class="example">hi</div>
</template>
  • 转化后
<!-- 转化规则是自己定义的 -->
<!-- 生产环境中,直接用hash值封装 -->
<style module>
._1TdbN_VT {
  color: red;
}
</style>
​
<template>
  <div class="._1TdbN_VT">hi</div>
</template>
​
<!-- 开发环境中,会显示来源 -->
<style module>
.src-views-login-Index__example {
  color: red;
}
</style>
​
<template>
  <div class=".src-views-login-Index__example">hi</div>
</template>

规则

  • Vue项目中的使用

在style标签中需要声明module特性:

<style module>
...
</style>

声明module特性后,Vue Loader会生成一个$style计算属性,向组件注入CSS Modules对象,我们可以通过使用该计算属性在template和JS中访问到CSS Modules对象。

<template>
    <!-- 直接通过$style来访问red类,同理$style作为计算属性也支持对象和数组语法 -->
  <p :class="$style.red">
    This should be red
  </p>
</template>
  • Composition:样式的组合
.classA {
    color: green;
    background: red;
}
​
.classB {
    composes: classA;
    color: red;
}
  • 使用composes规则可以把其他类和该类的样式组合起来

  • 要注意composes声明的规则必须在自身规则之前;

    可以一次性组合多个class,类名之间用空格隔开,但是这些class都必须是local scoped的

  • Dependencies:通过导入实现依赖

如果需要组合其他module里的样式,可以通过导入的方式:

.classC {
    composes: classA from './style.css'
}
  • 要注意当组合了不同CSS文件中的不同类时,CSS Modules是默认这些类之间不存在先后顺序的,因此导入时要保证这些类之间没有规则冲突
  • 组合的类之间不能存在循环依赖
  • composes实现的原理就是通过loader把import的CSS文件处理成ICSS格式的中间件,导出一个保存了所有local类名到global类名映射的对象,实际上这也是在JS文件中直接import CSS文件的原理

:global选择器

:global()允许括号中声明的选择器命中全局,即其类名不会经过规则封装,因此不受作用域的限制。

实际项目中,当我们希望修改所使用组件库的默认样式时,在使用CSS Modules方案的情况下,就可以通过:global()来修改其默认样式,但是要注意最好外面有一层类封装,否则可能影响全局样式。

Vue3新特性

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

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

  • 组合式api中的CSS Modules

在setup()中可以使用useCSSModuleAPI来获取module对象。

  • 在CSS中使用v-bind

支持在style中把某条rule的值和data中的一个数据绑定,比如:

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

Scoped CSS

原理

Vue Loader默认使用CSS后处理器PostCSS来实现Scoped CSS,原理就是给声明了scoped的样式中选择器命中的元素添加一个自定义属性,再通过属性选择器实现作用域隔离样式的效果。

  • 转化前
<style module>
.example {
  color: red;
}
</style>
​
<template>
  <div class="example">hi</div>
</template>
  • 转化后
<!-- 用自定义属性把类名封装起来了 -->
<style>
.example[data-v-f3f3eg9] {
  color: red;
}
</style>
​
<template>
  <div class="example" data-v-f3f3eg9>hi</div>
</template>

规则

  • 一个Vue文件中可以同时存在global和scoped的样式,即允许声明两个style标签。
<style>

</style>
​
<style scoped>

</style>
  • 使用Scoped CSS以后,因为样式具有了作用域,所以父组件的样式是不会影响到子组件的,即父组件和子组件的样式都具有自己的作用域。

    但是对于子组件的根元素来说,其样式还是可以受父组件控制的,使得父组件可以控制布局。

  • 注意通过v-html创建的DOM内容是不受Scoped CSS控制的,如果希望修改其中的样式,可以通过深度作用选择器。
  • 因为Scoped CSS是通过属性选择器实现的,所以最好不要和标签选择器混用,会产生性能问题。

深度作用选择器

  • 深度作用选择器使得父组件的样式可以渗透到子组件,其原理是使用后代选择器。

<style scoped>
.a :deep(.b) {
  
}
</style>
​

.a[data-v-f3f3eg9] .b {
  
}
  • 需要注意深度作用选择器和声明为global样式的区别,深度作用选择器只是为了能让父组件控制子组件样式,而global样式是全局起效的。

  • 实际项目中,当我们希望修改所使用组件库的默认样式时,在使用Scoped CSS方案的情况下,就可以通过深度作用选择器来修改其默认样式。

  • 几种深度左右选择器的写法:

    • /deep/:已废弃
    • >>>:在不使用Sass预处理器时可以使用
    • ::v-deep:使用Sass预处理器时使用

Vue3新特性

  • 深度作用选择器

    废弃/deep和>>>,使用:deep(.child-class)来替代::v-deep

  • :slotted()选择器

    支持使用:slotted(selector)来控制slot中的样式

  • :global()选择器

    当只有某些规则需要全局起效时,允许不重复声明一个全局作用域的style标签,而是使用:global(selector)来声明为全局样式。

二者的比较

CSS ModulesScoped CSS
需要在vue.config.js中额外配置Vue Loader默认支持,无需额外配置
通过根据配置的类命名规则,为元素生成独一无二的类名来实现作用域隔离通过给元素自定义hash属性,再使用属性选择器选中元素来实现作用域隔离
在style标签中声明module在style标签中声明scoped
支持导入其他module的样式,支持样式组合/
通过:global()来解除作用域的隔离,使样式在全局生效1. 可以定义全局样式,使样式不受作用域约束;2. 可以通过深度作用选择器命中子组件,从而控制子组件的样式

总结

到此这篇关于Vue项目中CSS Modules和Scoped CSS的介绍与区别的文章就介绍到这了,更多相关Vue中CSS Modules和Scoped CSS内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Vue项目中CSS Modules和Scoped CSS的介绍与区别

本文链接: https://www.lsjlt.com/news/143254.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Vue项目中CSS Modules和Scoped CSS的介绍与区别
    目录背景CSS Modules原理规则:global选择器Vue3新特性Scoped CSS原理规则深度作用选择器Vue3新特性二者的比较总结背景 在前端工程化飞速发展的时候,作为非...
    99+
    2024-04-02
  • css的scoped css和css module有哪些区别
    这篇“css的scoped css和css module有哪些区别”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下...
    99+
    2024-04-02
  • VUE中的v-if与v-show区别介绍
    1.共同点 都是动态显示DOM元素 2.区别 (1)手段:v-if是动态的向DOM树内添加或者删除DOM元素;v-show是通过设置DOM元素的display样式属性控制显隐;(2)...
    99+
    2024-04-02
  • CSS中absolute与relative的区别和联系
    本篇内容主要讲解“CSS中absolute与relative的区别和联系”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“CSS中absolute与relative...
    99+
    2024-04-02
  • Node.js 中的 module.exports 与 exports区别介绍
    目录介绍示例从源码中理解通过示例理解示例一示例二示例三示例四小结介绍 module:每个模块中都有 module 对象,存放了当前模块相关的信息;module.e...
    99+
    2024-04-02
  • 解析java.library.path和LD_LIBRARY_PATH的介绍与区别
    背景 近期要将算法部署到一个机群的虚拟主机(Debian 9.1 gcc 6.3.0)上,采用的是Java + JNI + shared library的方式来完成底层算法能力的部署...
    99+
    2024-04-02
  • Vue项目中new Vue()和export default{}的区别说明
    目录new Vue()和export default{}区别new Vue()export default{}import,export和export default注意问题new ...
    99+
    2024-04-02
  • css中margin和padding的区别
    css 中,margin 指定元素与周围元素的距离,padding 指定元素内容与元素边界的距离。两者默认值均为 0,margin 影响元素边框之外的区域,而 padding 影响边框之...
    99+
    2024-04-28
    css
  • PHP中empty()和isset()的区别介绍
    目录二者共同点二者区别1、对于未设置的变量的判断2、对于 "" (空字符串) 的判断3、对于 0 (作为整数的0) 的判断4、对于 0.0 (作为浮点数的0) 的判断5、对于 "0"...
    99+
    2024-04-02
  • TypeScript中let和var的区别介绍
    目录1、作用域不同2、let没有变量提升3、let变量不能重复声明4、for循环中的let与var1、作用域不同 用var声明的变量,只有函数作用域和全局作用域,没有块级作用域。而l...
    99+
    2024-04-02
  • Java中&和&&的区别简单介绍
    & 按位运算符,逻辑运算符 && 逻辑运算符 相同点:只要有一端为假,则语句不成立 假设有三个参数 int x = 1; int y = 2; int q =...
    99+
    2024-04-02
  • python中if和elif的区别介绍
    多个if语句是每次单独判断 比如: 例子一 a = 5 if a < 6: #条件1 print(1) if a < 7: #条件2 ...
    99+
    2024-04-02
  • css中class和id的区别
    css 中 class 和 id 的区别:用途:class 用于通用特征样式化,id 用于唯一元素标识。选择方式:class 用点符号(.),id 用哈希符号(#)。应用范围:class...
    99+
    2024-04-28
    css
  • CSS中组合与嵌套的用法介绍
    本篇内容主要讲解“CSS中组合与嵌套的用法介绍”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“CSS中组合与嵌套的用法介绍”吧!CSS组合与嵌套用法详解CSS组合...
    99+
    2024-04-02
  • css中的link和@import的区别
    css中的link和@import的区别:语法不同,link在html中使用<link>元素,@import在css中使用@import语句。导入方式不同,link直接插入h...
    99+
    2024-04-28
    css
  • Vue的v-if和v-show的区别图文介绍
    目录一、v-if和v-show区别二、生命周期三、性能的差异一、v-if和v-show区别 ① v-show严格意义来说其实是条件隐藏,直接在页面初始化的时候将DOM(对象模型)元素...
    99+
    2023-03-06
    Vue的v-if和v-show区别 Vue的v-if使用
  • CSS中padding和margin属性的写法介绍
    这篇文章主要讲解了“CSS中padding和margin属性的写法介绍”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“CSS中padding和margin属性...
    99+
    2024-04-02
  • vue项目中路径使用@和~的区别及说明
    目录vue路径使用@和~的区别1. @ 使用说明2. ~ 使用说明@和~@符号路径解决@路径别名的学习如果让编辑器支持@~@路径的解决总结vue路径使用@和~的区别 首先:@和~ 都...
    99+
    2022-12-08
    vue路径 @和~的区别 路径使用@和~区别
  • Vue项目中关于全局css的处理
    目录步骤一:定义声明全局CSS的样式文件(common.scss)步骤二:挂载到全局封装一:对common.scss拆分封装二:新建index.scss,对elementPlus或者...
    99+
    2023-05-16
    Vue关于全局css的处理 关于全局css的处理 Vue处理css
  • MySQL中in与exists的使用及区别介绍
    先放一段代码 for(int i=0;i<1000;i++){ for(int j=0;j<5;j++){ System.out.println("hello"); } } for...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作