Vue 开发中为什么要使用穿透符::deep()

server/2024/11/29 15:20:30/

在 Vue 开发中,有时候样式需要穿透才能生效,通常是因为使用了作用域样式 (scoped styles) 的缘故。


1. 什么是作用域样式 (scoped styles)?

在 Vue 单文件组件 (SFC) 中,使用 <style scoped> 声明的样式只会作用于当前组件的元素。Vue 在编译时会通过生成唯一的动态属性(如 data-v-xxxxxx)的方式,为每个组件的 DOM 节点加上标记,从而实现样式的作用域隔离。

例如:

<template><div class="box">Hello</div>
</template><style scoped>
.box {color: red;
}
</style>

编译后,HTML 可能会变成:

<div class="box" data-v-123abc>Hello</div>

CSS 会变成:

.box[data-v-123abc] {color: red;
}

2. 为什么有时需要样式穿透?

有些情况下,你需要修改子组件或第三方库中的样式,这些样式可能处于另一个作用域或者被深层封装。直接在 <style scoped> 中定义样式通常无法生效,因为作用域样式只针对当前组件的 DOM 节点。

例如,想要覆盖子组件的样式:

<template><child-component></child-component>
</template><style scoped>
/* 尝试覆盖子组件内部的样式 */
.some-class {color: blue;
}
</style>

以上代码不会生效,因为 .some-class 的作用域被限制在父组件,无法穿透到子组件或其内部的 DOM。


3. 如何实现样式穿透?

在 Vue 3 中,::deep() 是用于样式穿透的一种语法,替代了之前的 /deep/>>> 的用法。它允许你跨越作用域样式的限制,修改子组件或嵌套元素的样式。这样,你可以在父组件中应用样式来影响子组件的样式,尤其是当你无法直接修改子组件代码时。

::deep() 用法

::deep() 是一个 Vue 3 中的特殊选择器,用来进行样式穿透,能够影响嵌套的子组件样式。它是一个更为正式和规范的方式,代替了 Vue 2 中使用的 /deep/>>>

基本语法
<template><child-component></child-component>
</template><style scoped>
::deep(.child-class) {color: red;
}
</style>

在这个例子中,::deep(.child-class) 会将 .child-class 类的样式应用到 child-component 组件内的 .child-class 元素上,即使它是在子组件中定义的,也能被父组件的样式影响。

具体解释

  • ::deep() 可以用来选择子组件内的 DOM 元素或样式,突破组件的作用域限制。
  • 它的作用类似于一个全局选择器,能够选择嵌套组件内部的元素,虽然这些元素本身是被 scoped 样式保护的。
  • ::deep() 还可以用于组合选择器、伪类、伪元素等。

例子:穿透嵌套子组件

假设有一个子组件 ChildComponent.vue,其中有一个 .btn 类的按钮样式,你希望在父组件中控制这个按钮的样式。

子组件 ChildComponent.vue

<template><button class="btn">Click me</button>
</template><style scoped>
.btn {background-color: green;color: white;
}
</style>

父组件 ParentComponent.vue

<template><child-component></child-component>
</template><style scoped>
::deep .btn {background-color: red; /* 覆盖子组件按钮的背景色 */color: yellow;         /* 改变文字颜色 */
}
</style>

在这个例子中,::deep .btn 会把父组件的样式应用到子组件的 .btn 按钮上,将其背景色从绿色改为红色,文字颜色改为黄色。

::deep() 的注意事项

  1. 全局影响:虽然 ::deep() 可以穿透作用域样式,但它仍然会影响到子组件的样式,因此可能会导致子组件的样式被外部影响,破坏组件的封装性。要谨慎使用。

  2. 仅适用于 scoped 样式::deep() 主要用于作用域样式下的穿透,如果不使用 scoped,那么你就不需要使用 ::deep(),样式本来就没有作用域隔离。

  3. Vue 3 新特性::deep() 是 Vue 3 引入的语法。如果你使用的是 Vue 2,应该使用 /deep/>>>


4. 小结

在实际开发中,优先考虑保持组件样式隔离,避免直接修改子组件样式,以提高组件的可维护性和独立性。


http://www.ppmy.cn/server/145937.html

相关文章

【Qt】QDateTimeEdit控件实现清空(不保留默认时间/最小时间)

一、QDateTimeEdit控件 QDateTimeEdit 提供了一个用于编辑日期和时间的控件。用户可以通过键盘或使用上下箭头键来增加或减少日期和时间值。日期和时间的显示格式根据设置的格式显示&#xff0c;可以通过 setDisplayFormat() 方法来设置。 二、如何清空 我在使用的时候&#…

第十二章 使用 BIND 提供域名解析服务

1. DNS 域名解析服务 相较于由数字构成的 IP 地址&#xff0c;域名更容易被理解和记忆&#xff0c;所以我们通常更习惯通过域名的方式来访问网络中的资源。但是&#xff0c;网络中的计算机之间只能基于 IP 地址来相互识别对方的身份&#xff0c;而且要想在互联网中传输数据&…

Anaconda3 2024 jupyter notebook 配置默认文件路径

我的版本如下&#xff1a; 第一步&#xff1a; 打开命令行anaconda prompt &#xff0c; 敲下面命令生成配置文件 jupyter notebook --generate-config 如下图&#xff1a; 修改配置jupyter_notebook_config.py 文件中搜索c.ServerApp.root_dir &#xff08; 对于 Anac…

windows 应用 UI 自动化实战

UI 自动化技术架构选型 UI 自动化是软件测试过程中的重要一环&#xff0c;网络上也有很多 UI 自动化相关的知识或资料&#xff0c;具体到 windows 端的 UI 自动化&#xff0c;我们需要从以下几个方面考虑&#xff1a; 开发语言 毋庸置疑&#xff0c;在 UI 自动化测试领域&am…

Spring Bean初始化流程

首先&#xff1a; 加载Bean定义(Configuration) 然后对于每个Bean&#xff1a; 1、实例化Bean&#xff08;应该是从Bean方法中获取&#xff0c;Bean方法里面包含new这个类型的代码&#xff09;2、依赖注入&#xff08;所依赖的Bean要经历相同的流程&#xff09;、调用Setter…

Docker化部署Flask:轻量级Web应用的快速部署方案

Flask是一个用Python编写的轻量级Web应用框架&#xff0c;以其简洁性和灵活性而受到开发者的喜爱。Docker作为一种流行的容器化技术&#xff0c;为应用的部署和管理提供了极大的便利。本文将探讨Flask的优点、Docker部署的好处&#xff0c;并详细介绍如何将Flask应用Docker化部…

嵌入式开发之IO多路复用(一)

目录 1、IO模型和多路复用模型 1.1、阻塞I/O模式 1.1.1、读阻塞 1.1.2、写阻塞 1.2、非阻塞模式I/O 1.3、信号驱动I/O 1.4、多路复用I/O 1.4.1、IO多路复用步骤: 1.4.2、伪代码示例讲解 1、IO模型和多路复用模型 在UNIX、Linux下主要有4种I/O模型: 阻塞I/O: 最常用…

HBase运维需要掌握的技能(1)

作为 HBase 运维人员&#xff0c;我们需要掌握一定的 HBase 和 Hadoop 生态系统相关的知识&#xff0c;特别是与系统安装、配置、性能调优、故障排除等相关的技能。以下是 HBase 运维人员需要掌握的核心知识点&#xff1a; HBase 是一个分布式的、面向列的 NoSQL 数据库&#…