博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Vue2的/deep/深度选择器失效了?

Posted on 2023-07-26 22:59  kpi311  阅读(2732)  评论(0编辑  收藏  举报

/deep/ 在 Vue2 样式中的问题。

太长不看:

不要在 Vue SFC 以外的地方使用/deep/。对于 Vue3 ,请使用最新的:deep()伪类选择器。

什么是/deep/

/deep/是 Vue2 中一个重要的样式选择器,可以用于选择封装好的组件内部的样式。

如果直接在 Vue 组件上设置 class 属性,该属性只附加于子组件的最外层 DOM ,无法深入选择。

Vue 在编译模板代码时,会将/deep/动态替换成[data-xxx-xxx]的形式,变成一个属性选择器,这个属性选择器是动态生成且唯一的,能够有效增加权重,并实现精确选择。

/deep/的由来

/deep/其实曾经是进入过提案的选择器,被称作 Shadow boundary-piercing combinators ,用来选择 web-components 中 shadow-root 里的样式。直到 2017 年才从 chrome 中移除。移除之后也不是完全没用了,而是退化成后代选择器(也就是说,还能被浏览器解析)。

考虑到 Vue2 设计发展的年代,引入 boundary-piercing 这个概念,并模仿选择器也是很合理的。Vue3 就完全拿掉了SFC CSS Features | Vue.js (vuejs.org)

/deep/失效的原因

Vue 能够编译/deep/选择器是因为 vue-loader 的工作:CSS 作用域 · vue-loader (vuejs.org)

而对于 less 而言,只会将这个选择器直接原样输出。对于大部分 Webpack 项目,less 文件一般通过 less-loader 加载,lessc 编译,传递给 css-loader,最后经由 style-loader 在 html 文件中添加 style 标签。style-loader - npm (npmjs.com)

在 89 版本以前的 chrome,可以识别 xxx /deep/ ooo,并解析为后代选择器(空格)。但 89 版本之后就完全不能解析这个选择器了,也就呈现出完全无效的情况。

总结

  1. Vue SFC 中/deep/没有问题,放心使用。反之,单独的 less/sass/css 文件坚决不要用;
  2. Vue2 项目尽早转向 Vue3 项目,和历史包袱说再见。