一文彻底搞懂Vue中scoped和/deep/原理

 更新时间:2023年08月08日 10:47:43   作者:liuwei9413  
在Vue中,有两种常用的CSS选择器,用于修改组件样式:scoped 和 /deep/(或 ::v-deep),它们都是为了实现样式的作用域,本文小编就来分别给大家介绍一下这两种选择器的原理,需要的朋友可以参考下

背景

我们做 Vue 项目在组件里写 css 的时候,经常会给 <style> 标签加上 scoped ,比如这样: <style lang="less" scoped> ,这样写出来的 css 就是局部的,不会影响其他组件。

另外,假设我们在自己的组件中引入了一个子组件,并且希望在我的组件中修改子组件中的样式,由于我们用了 scoped ,直接修改是不生效的。去掉 scoped 是可以的,不过没了局部 css 风险不可控。有一种更好的方式,用深度选择器修改,比如 less 中的 /deep/ 。用过组件库(如 element ui )的朋友,在覆盖组件库样式的时候应该会经常用到深度选择器 /deep/

基于以上两点,我们来聊一聊:

  1. 为什么 scoped 可以形成局部 css ?原理是什么?
  2. 为什么 /deep/ 可以跨组件修改 css ?原理是什么?

scoped 形成局部 css 原理

先看一张图:

image.png

我们审查 html 元素时发现多了很多类似 data-v-f321cf6 属性,这些属性其实就是 scoped hash 出来的。

再来看一张页面生成的 css 截图:

image.png

仔细看第一张图标记了两种颜色,他们分别对应两种 hash 属性值: data-v-f5321cf6 data-v-6a6ef68c ,其实这里就是两个不同的组件生成的两个不同的值,每个加过 scoped 的组件生成的值都是唯一的。

结合两张图,不难发现 scoped 形成局部 css 的原理其实很简单,就是先给元素加上 hash 出来的属性,再通过属性选择器来选择这些元素,由于每个组件 hash 出来的属性值都是唯一的, css 属性选择器选出来的元素当然也是组件级的了,因为形成了组件内局部 css

/deep/  跨组件修改 css  原理

一个例子

一个列表页面 ,需要在数据为空的时候展示空白页,这个空白页我们引入的是第三方组件库的空白页组件 <no-data>

image.png

假设我们现在要修改空白页组件中图片的宽高, <no-data> 不支持传入宽高,并且我们无法改动这个第三方组件,只能在列表页通过 css 覆盖空白页组件的样式。

我们第一时间想到改样式嘛,这还不简单,于是写下:

<style lang="less" scoped>
.no-data{
    img {
        width: 200px;
        height: 200px;
    }
}
</style>

自信满满的点开浏览器查看效果,发现设置的宽高并没起到作用,空白页图片还是默认的偏大。

仔细一想,父组件用了 scoped 是不能直接改子组件内样式的,得用 /deep/ ,于是乎有了下面的代码:

<style lang="less" scoped>
.no-data{
    /deep/img {
        width: 200px;
        height: 200px;
    }
}
</style>

再查看效果:

image.png

生效了,图片小了很多!

我们再来审查一下页面渲染出来的代码,没加 /deep/ 的:

image.png

注意看 css 部分,这里的选择器是 .acl-nodata img[data-v-6a6ef68c] ,这里的 data-v-6a6ef68c 属性是 <no-data> 组件中的 scoped 生成的。

接着往下看,加上 /deep/ 后的:

image.png

还是重点看 css 部分,这里的选择器是 .integral-detail .no-data[data-v-f5321cf6] img ,这里的 data-v-f5321cf6 是列表页的 scoped 生成的。

核心区别在于: img[data-v-6a6ef68c] .no-data[data-v-f5321cf6] img

/deep/ 原理

通过上面的例子,我们可以分析出,在使用了 /deep/ 选择器后,会把当前元素 img [data-v-6a6ef68c] 干掉,并通过他的父级(准确的说是 img 元素所属空白页组件的根元素 <div ></div> ),来查找到 img ,也就是通过 .no-data[data-v-f5321cf6] img 来定位到 img 元素。

因为我们的代码是在列表页写的,列表页 hash 出来的属性是 [data-v-f5321cf6] ,在我们使用 /deep/ 之前, img hash [data-v-6a6ef68c] ,在列表页中的 css 代码当然是识别不到空白页组件的 [data-v-6a6ef68c] ,所以修改宽高不生效。使用 /deep/ 之后,通过 .no-data[data-v-f5321cf6] img ,由于 [data-v-f5321cf6] 本身就是列表 hash 出来的,自然是可以识别的,修改宽高自然也就生效了。

为了加深理解,这里再提一点,仔细看 <div ></div> 这一块的 html 代码,你会发现它是同时具有 [data-v-f5321cf6] [data-v-6a6ef68c] 两种属性,因为 <no-data> 组件的根元素是 <div ></div> ,在列表页引入 <no-data> <div ></div> 也相当于是列表中的一个元素,所以 scoped 也会给它 hash [data-v-f5321cf6] 。 (这一块在实际开发中,有些朋友会搞一些骚操作,比如在父组件和子组件同时改 .no-data

以上就是一文彻底搞懂Vue中scoped和/deep/原理的详细内容,更多关于Vue scoped和/deep/原理的资料请关注脚本之家其它相关文章!

相关文章

  • vue中 数字相加为字串转化为数值的例子

    vue中 数字相加为字串转化为数值的例子

    今天小编就为大家分享一篇vue中 数字相加为字串转化为数值的例子,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-11-11
  • VUE3自定义指令防止重复点击多次提交的实现方法

    VUE3自定义指令防止重复点击多次提交的实现方法

    vue3项目,新增弹框连续点击确定按钮防止多次提交,在按钮上添加自定义指令,这篇文章主要介绍了VUE3自定义指令防止重复点击多次提交的实现方法,需要的朋友可以参考下
    2024-08-08
  • vue中如何下载excel流文件及设置下载文件名

    vue中如何下载excel流文件及设置下载文件名

    这篇文章主要介绍了vue中如何下载excel流文件及设置下载文件名,对vue感兴趣的同学,可以参考下
    2021-05-05
  • vue使用国密SM4进行加密、解密的过程

    vue使用国密SM4进行加密、解密的过程

    国密SM4算法是一种对称加密算法,适用于对称密钥加密和解密的场景,这篇文章主要介绍了vue使用国密SM4进行加密、解密,需要的朋友可以参考下
    2023-07-07
  • Vue3中事件总线的具体使用

    Vue3中事件总线的具体使用

    本文主要介绍了Vue3中事件总线的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • Vue3进行打包配置的优化指南

    Vue3进行打包配置的优化指南

    随着 Vue3 项目的业务迭代,打包体积过大、首屏加载缓慢逐渐成为影响用户体验的核心问题,本文将详细介绍如何通过精细化的打包配置,实现代码分包、剔除冗余 Console 日志,并结合最佳实践,帮助你将项目打包体积缩减 70%,首屏加载速度提升 60%
    2026-06-06
  • Vue2.x配置路由导航守卫实现用户登录和退出

    Vue2.x配置路由导航守卫实现用户登录和退出

    之前在Vue的学习中通过路由导航守卫控制实现了用户登录模块的功能,本文基于Vue2.x进行实现,在此将实现过程进行记录与总结,感兴趣的可以了解一下
    2021-08-08
  • Vue鼠标右键画矩形和Ctrl按键多选组件方式

    Vue鼠标右键画矩形和Ctrl按键多选组件方式

    文章介绍了一个Vue组件,该组件允许用户通过鼠标右键在画布上绘制矩形,并且支持通过Ctrl键进行多选,文章附带了组件代码和一个示例,建议读者将代码复制到自己的开发环境中进行调试
    2024-12-12
  • vue3声明字段名为枚举的类型详解

    vue3声明字段名为枚举的类型详解

    这篇文章主要介绍了vue3声明字段名为枚举的类型方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-09-09
  • vue props 一次传多个值实例

    vue props 一次传多个值实例

    这篇文章主要介绍了vue props 一次传多个值实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-07-07

最新评论