VueJS 之样式冲突与样式穿透

news2024/11/20 20:34:10

文章目录

  • 参考
  • 描述
  • 样式冲突
      • 现象
      • scoped
      • 原理
  • 样式穿透
      • 深度选择器
          • 使用
          • 原理
      • 顶层元素
          • 局限性

参考

项目描述
搜索引擎Bing
哔哩哔哩黑马程序员

描述

项目描述
Edge109.0.1518.70 (正式版本) (64 位)
操作系统Windows 10 专业版
@vue/cli5.0.8
npm8.19.3
VueJS2.6.14

样式冲突

在使用 Vue 进行前端工程化开发后,对 Vue 进行打包的过程中将会把所有组件中的所有样式代码都转移到 Vue 项目中的 index.html 文件中。也就是说,在默认情况下,在组件的 style 元素内部编写的样式代码能够影响的并不只是当前的组件。这种情况容易导致样式之间发生冲突(样式的覆盖),不利于 Vue 项目的组件化开发。

现象

App.vue

<template>
  <div class="container">
    <h3>TwoMoons</h3>
    <Child></Child>
  </div>
</template>

<script>
// 导入组件
import Child from '@/components/Child.vue';
export default {
  // 注册组件
  components: {
    Child
  }
}
</script>

<style>
/* 为 h3 标签设置样式 */
h3{
    color: #f40;
    font-size: 18px;
}
</style>

Child.vue

<template>
  <div class="child">
    <h3>RedHeart</h3>
  </div>
</template>

<script>
export default {

}
</script>

<style>

</style>

效果:

效果

我仅在组件 App.vue 中为 h3 元素设置了样式,可是这个样式影响到了另外的组件中的 h3 元素。

scoped

VueJS 提供了 scoped 属性,将该属性应用到组件中的 style 元素中,就能够避免发生样式冲突。

修改 App.vue

<template>
  <div class="container">
    <h3>TwoMoons</h3>
    <Child></Child>
  </div>
</template>

<script>
// 导入组件
import Child from '@/components/Child.vue';
export default {
  // 注册组件
  components: {
    Child
  }
}
</script>

// 添加 scoped 属性,防止发生样式冲突
<style scoped>
/* 为 h3 标签设置样式 */
h3{
    color: #f40;
    font-size: 18px;
}
</style>

效果:

效果

原理

在组件中使用 scoped 后,将在当前组件中的 template 元素内的元素中添加一个形如 data-v-* (每一个组件的 data-v-* 都不相同)的自定义属性。除此之外,VueJS 还将自动在原有的 CSS 选择器中添加属性选择器以选择带有自定义属性 data-v-* 的元素。
通过以上两点处理,我们就可以仅选择本组件中的元素进行样式设置了。

在浏览器中打开开发者工具观察上一个示例,你将有如下发现:

自定义属性

元素

属性选择器

属性

样式穿透

深度选择器

在为元素添加 scoped 后,当前组件的样式并不会应用到子组件中。在开发过程中,我们可能需要使用到第三方组件,在第三方组件中修改样式并不推荐,这样做容易造成混乱。我们需要在父组件中对其进行修改,为此我们可以使用深度选择器。
深度选择器可以在保证不发生全局样式冲突的前提下,将父组件中的样式应用到子组件(准确来说应该是当前组件的所有后代组件)中。深度选择器存在三种类型,它们分别对应不同的使用场景。

项目描述
CSS>>>
Less/deep/
Scss::v-deep

虽然三种深度选择器的应用场景不同,但三者的使用方式类型。在演示过程中仅使用 CSS 场景下的深度选择器。

使用

App.vue

<template>
  <div class="container">
    <h3>TwoMoons</h3>
    <Child></Child>
  </div>
</template>

<script>
// 导入组件
import Child from '@/components/Child.vue';
export default {
  // 注册组件
  components: {
    Child
  }
}
</script>

// 添加 scoped 属性,防止发生样式冲突
<style scoped>
/* 使用 CSS 场景下的深度选择器实现样式穿透 */
>>> h3{
    color: #f40;
    font-size: 18px;
}
</style>

Child.vue

<template>
  <div class="child">
    <h3>RedHeart</h3>
  </div>
</template>

<script>
export default {

}
</script>

<style>

</style>

效果:

效果

父组件中的样式在添加了 scoped 属性的情况下应用到了子组件中。

注:

在使用深度选择器时,你的编辑器也许会在深度选择器下显示红色波浪线以提示开发者代码编写错误,请不要理会,深度选择器在 VueJS 中是合理的。

原理

请使用开发者工具观察上个示例,你将会有如下发现:

属性
属性

可以看到使用了深度选择器后,style 元素的子元素的属性并没有发太大变化(相比没有使用深度选择器而 style 添加了 scoped 属性的情况)。

选择器

选择器

为了选择当前组件的子组件中的元素进行样式设置,先使用属性选择器选择自定义属性以指定当前组件(不同的组件 ,VueJS 为其分配的自定义属性 data-v-* 不同),再通过后代选择器选择当前组件的后代组件中的相应元素。

顶层元素

相信各位也都发现了一个问题,即子组件的顶层元素也被添加了当前组件所独有的自定义属性。

属性

这意味着我们可以不使用深度选择器,达到样式穿透的目的,只是这种方法的局限性更大。

App.vue

<template>
  <div class="container">
    <h3>TwoMoons</h3>
    <Child></Child>
  </div>
</template>

<script>
// 导入组件
import Child from '@/components/Child.vue';
export default {
  // 注册组件
  components: {
    Child
  }
}
</script>

// 添加 scoped 属性,防止发生样式冲突
<style scoped>
h3{
    color: #f40;
    font-size: 18px;
}
</style>

Child.vue

<template>
  <!-- 将需要被样式穿透的元素放置为当前组件的顶层元素 -->
  <h3>RedHeart</h3>
</template>

<script>
export default {

}
</script>

<style>

</style>

效果:

效果

效果

局限性
  1. 由于组件中的 template 元素内仅允许使用一个根元素,即仅能存在一个顶层元素,所以使用该方式仅能选中子组件中的单个元素。
  2. 该方式并不像深度选择器可以选中当前组件的后代组件中的相应元素,仅能选中子组件中的相应元素。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/194283.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大文件上传/下载

一、前言 大文件上传下载一直以来是前端常用且常考的热门话题。本文将分别介绍大文件上传/下载的思路和前端实现代码。 二、分片上传 整体流程 对文件做切片&#xff0c;选择文件后&#xff0c;对获取到的file对象使用slice方法可以将其按照制定的大小进行切片&#xff0c;…

使用matplotlib,pylab进行python绘图

一提到python绘图&#xff0c;matplotlib是不得不提的python最著名的绘图库&#xff0c;它里面包含了类似matlab的一整套绘图的API。因此&#xff0c;作为想要学习python绘图的童鞋们就得在自己的python环境中安装matplotlib库了&#xff0c;安装方式这里就不多讲&#xff0c;方…

openmmlab学习打卡1

openmmlab学习打卡1通用视觉框架 OpenMMLab通过 conda 安装通用视觉框架 OpenMMLab 基于pytorch实现 其中&#xff1a; 分类算法在 mmclassification 模块下 目标检测在 mmdetection 模块下 分割模型在 mmsegmentation 模块下&#xff08;openmmlab 2.0 版本中加入&#xff09…

洛谷P1885 Moo —— 搜索

This way 题意&#xff1a; 奶牛 Bessie 最近在学习字符串操作&#xff0c;它用如下的规则逐一的构造出新的字符串&#xff1a; S(0)S(0) S(0) moo S(1)S(0)S(1) S(0) S(1)S(0) m ooo S(0) S(0) S(0) moo m ooo moo moomooomoo S(2)S(1)S(2) S(1) S(2)S(1) m oooo S(…

无js实现拖拽边框改变大小的笔记

前言 最近刷抖音看到一款游戏"拣爱",看到这个人手动拖动的很有意思,就想着能不能前端实现,来学习学习,虽然说最终的效果没有gif图片那么好,但是也算实现了,吧… 具体原理 利用resize属性所出现的小拖拽条 再配合::-webkit-scrollbar设置拖拽区域宽度,高度,结合opac…

手动签发证书配置nginx

openssl和ssh基本用法 通过OpenSSL工具生成证书 创建私钥 openssl genrsa -des3 -out server.key 2048 注意&#xff0c;centos版本如果是CentOS Linux release 8.0.1905 (Core)版本&#xff0c;私钥长度不能设置成1024位&#xff0c;必须2048位。不然再最后启动nginx时会出…

java之数组模块

数组定义格式1.1数组概述一次性声明大量的用于存储数据的变量要存储的数据通常都是同类型数据&#xff0c;例如&#xff1a;考试成绩1.2什么是数组数组(array)是一种用于存储多个相同类型数据的存储模型1.3数组的定义格式格式一&#xff1a;数据类型[] 变量名范例&#xff1a; …

h5实现相机

什么是取景器 取景器是什么&#xff1f;取景器是相机的一个专业术语&#xff0c;在前端就是扫描拍照 取景器的实现原理 请求手机的一个媒体类型的视频轨道&#xff0c;利用一个div或者图片作为上层蒙层&#xff0c;然后在利用canvas绘制视频中某一帧的画面绘制为图片。 前期…

HTML基础知识

一个网站由两部分组成&#xff1a;前端和后端。前端主流语言目前是HTML、CSS、JS等。HTML只是描述了页面的内容&#xff08;骨架&#xff09;&#xff0c;CSS才是描述了页面的样式。HTML结构HTML标签HTML代码是由“标签”构成的&#xff0c;HTML描述了页面上有什么东西&#xf…

数字化转型导师坚鹏:银行数字化转型为什么需要融合王阳明心学

在BLM银行数字化转型方法论中&#xff0c;我之所以融合BLM模型与王阳明心学&#xff0c;作为一个工科背景并拥有多年软硬件产品研发经验的人来说&#xff0c;深刻地知道很多人利用了科技的力量做了大量的恶事&#xff0c;而不是善事&#xff0c;如黑客大量盗取、泄漏、贩卖客户…

ESLint 的一些理解

ESLint ESLint 是在 ECMAScript/JavaScript 代码中识别和报告模式匹配的工具&#xff0c;它的目标是保证代码的一致性和避免错误。 为什么要使用ESLint 有的可以帮我们避免错误&#xff1b;有的可以帮我们写出最佳实践的代码&#xff1b;有的可以帮我们规范变量的使用方式&a…

Docker入门之使用Dockerfile 构建镜像(七)

文章目录1. 前言2. Docker file 核心要点2.1 注意事项2.2 Docker file 执行流程2.3 Docker Image、Docker file、Docker Container区别2.4 Dockerfile常用保留字指令2.4.1 FROM2.4.2 MAINTAINER2.4.3 RUN2.4.4 EXPOSE2.4.5 WORKDIR2.4.6 USER2.4.7 ENV2.4.8 ADD2.4.9 COPY2.4.1…

ansible 简单使用

运行过程 1.加载自己的配置文件&#xff0c;默认/etc/ansible/ansible.cfg&#xff1b; 2.查找对应的主机配置文件&#xff0c;找到要执行的主机或者组&#xff1b; 3.加载自己对应的模块文件&#xff0c;如 command&#xff1b; 4.通过ansible将模块或命令生成对应的临时py文…

OpenMMLab 实战营打卡 - 第 一 课

OpenMMLab 实战营打卡 - 第 一 课 复习下总忘的基础知识 卷积的通道数变化 前一层特征纬度&#xff08;通道数&#xff09;决定核的通道数 当前层输出的特征纬度&#xff0c;由核的数量决定 图像尺寸变化 padding 公式&#xff1a;H′H−K12pH^{\prime}H-K12 pH′H−K12p…

电源技术中的安森美 单通道电压电平转换器件FXLP34P5X 适合便携式应用方案

电源技术中的安森美 单通道电压电平转换器件FXLP34P5X 适合便携式应用方案 &#xff1a;输入转换器电源电压为VCC1&#xff0c;输出转换器电源电压为VCC。 该器件使用1.0V至3.6V的VCC值运行&#xff0c;主要用于要求超低功耗的便携式应用。内部电路由最小量的缓冲器级组成&…

普通大学生自学 JAVA 怎样才能进大厂?

前言 可以看一下现在大厂对于Java方面的要求 阿里 百度 腾讯 从上面可以看出&#xff0c;无论是阿里、百度亦或是腾讯对于Java方面的要求是比较高的&#xff0c;可以说要求的是一个全面&#xff0c;所以想要进入大厂&#xff0c;不能操之过急&#xff0c;需要先从基础做起&am…

php报错SERVER SENT CHARSET (255) UNKNOWN

配置文件PHP.ini修改打开; extension_dir "ext"&#xff0c;修改成; extension_dir "./" ; On windows: extension_dir "自己php的存放路径\ext"2.打开extensionmsql.dll; For example, on Windows: ;extensionmsql.dll3.修改配置&#xff08…

五、Linux 用户管理常用命令

一、用户管理命令 - useradd 命令名称&#xff1a;useradd 命令所在路径&#xff1a;/usr/sbin/useradd 执行权限&#xff1a;root 功能描述&#xff1a;添加新用户 语法&#xff1a;useradd 用户名 二、用户管理命令 - userdel 命令名称&#xff1a;userdel 命令所在路…

创业青年张继群

中央广播电视总台 -专访-张继群简介&#xff1a; 张继群&#xff0c;1995年10月生&#xff0c;男&#xff0c;临沂大学硕士研究生在读&#xff0c;现临沂城投思索信息技术有限公司智慧城市事业部员工&#xff0c;作为农业专班成员主要从事网络安全、大数据等新一代信息技术的科…

nuxt3:postcss-pxtorem

一、理解postcsshttps://www.postcss.com.cn/1.1、PostCSS是一个用 JavaScript 工具和插件转换 CSS 代码的工具。1.2、增强代码可读性&#xff1a;利用从 Can I Use 网站获取的数据为 CSS 规则添加特定厂商的前缀。 Autoprefixer 自动获取浏览器的流行度和能够支持的属性&#…