- 开始时间:2020-01-21
- 目标主要版本:2.x 、3.x
- 引用 issue:N/A
- 实现的 PR:N/A
摘要
在单文件组件中 scoped 的 style 中提供更一致的自定义 CSS 扩展。
基本范例
<style scoped>/* deep selectors */::v-deep(.foo) {}/* shorthand */:deep(.foo) {}/* targeting slot content */::v-slotted(.foo) {}/* shorthand */:slotted(.foo) {}/* one-off global rule */::v-global(.foo) {}/* shorthand */:global(.foo) {}</style>
动机
Vue 的单文件的 scoped style 使 CSS 仅应用于当前组件。有一些用户经常遇到的情况是可以改进的。
deep 选择器
有些时候,我们可能想明确地让一条规则针对子组件。
最初,我们支持 >>> 组合器使选择器“深入”。然而,一些 CSS 预处理器,如 SASS 在解析它时有问题,因为这不是一个正式的 CSS 组合器。
我们后来改用了 /deep/,它曾经是 CSS 的一个实际提案的附加项(甚至在 Chrome 中原生支持),但后来放弃了。这给一些用户带来了困惑,因为他们担心在 Vue SFC 中使用 /deep/ 会使他们的代码在放弃该功能的浏览器中得不到支持。然而,就像 >>> 一样,/deep/ 只是作为 Vue 的 SFC 编译器重写选择器时的一个提示,并在最终的 CSS 中被删除。
为了避免被丢弃的 /deep/ 组合器的混乱,我们引入了另一个自定义的组合器,::v-deep,这次更明确的支持这是一个 Vue 特定的扩展,并使用伪元素语法,这样任何预处理器都应该能够解析它。
由于兼容性的原因,在当前的 Vue2 SFC 编译器仍然支持以前版本的 deep 组合器,这又会让用户感到困惑。在 Vue3 中,我们正在废除对 >>> 和 /deep/ 的支持。
当我们正在为 Vue3 开发新的 SFC 编译器时,我们注意到 CSS 伪元素实际上在语义上不是组合器。伪元素接受参数更符合 CSS 的习惯,所以我们也让 ::v-deep() 以这种方式工作。如果你不关心明确的 v- 前缀,你也可以使用更短的 :deep() 变体,其工作原理完全相同。
目前仍然支持 ::v-deep 作为组合器的用法,但它被认为是过时的,并会引起警告。
定位/避免 slot 内容
目前,从父组件传过来的 slot 内容既受父组件 scoped 样式的影响,也受子组件 scoped 的样式影响。没有办法编写只针对插槽内容的明确规则,或不影响插槽内容的规则。
在 v3 中,我们打算让子组件的 scoped 样式默认不影响插槽的内容。要明确的针对插槽的内容,可以使用 ::v-slotted()(简称 ::slotted())伪元素。
一次性的 Global 规则
目前,要添加一个全局性的 CSS 规则,我们需要使用一个单独的非范围(没有 scoped)的
