在 Vue
项目的开发中,很多人都因为想要限制 CSS
样式的作用范围(避免样式污染的问题)去使用 scope
属性。
但是很多的情况下都会去修改分装好的子组件以及 UI 库中的组件样式,所以经常会用到 样式穿透 这个东西,因为我以前是使用的 Stylus
作为样式预处理器的,所以并没有感觉到什么困惑的地方,但是有很多同学是使用的 Scss
以及 Less
的,对于他们来说什么时候使用 /deep/
什么时候使用 ::v-deep
是很困扰的。特别是对于一些刚刚进入前端圈的小伙伴们。
正好最近在思否也遇到了很多人来问这样的问题,就像一次性都把相关的疑问都回答了。
我想要书写样式穿透的时候应该怎么办?
在 Vue2
版本中:
- 如果你是使用的
Stylus
以及CSS
那么不用考虑直接使用CSS
所支持的>>>
来穿透就可以了。 - 如果说你使用的是
Less
以及Sass
的话,那么推荐使用::v-deep
来实现样式穿透的效果。
为什么不使用 /deep
呢,因为现在的 Sass
默认安装的是 dart-sass
如果你使用 /deep/
会提示错误:SassError: expected selector. /deep/
,所以直接使用 ::v-deep
预防可能会出现的问题。
并且最好不要直接使用 ::v-deep
等样式穿透来书写,比如说:
<style scoped lang="scss"> ::v-deep .className { ... } </style>
这样的话,其实就和你没有添加 scope
的结果是一样的了,并不会只限制在当前组件内。而会污染到全局样式当中。
并且直接使用 /deep/ .className
可能无法通过 loader
的编译。
如果说你使用的是 Vue3
的话,就需要把 ::v-deep
替换成 :deep()
了
如果是添加到 body
元素上的组件怎么办,比如说 el-dialog
这种弹窗组件。
一般都会提供一个 custom-class
给你使用,可以借助这个来起一个 className
来给它们添加样式,或者可以直接使用 class
来给当前页面中的弹窗元素起一个 CSS 类名。
然后写在全局就可以了,没有必要通过样式穿穿透来覆写。当然也可以写在 scope
内,因为第一级会被添加上当前组件的 hash
值。来起到限制作用域的要求。