Vue2中如何在Sass后缀(&__)选择器上使用::v-deep?
问题根因
你当前写法失效的核心原因是:Sass的父选择器标识符&会将父级完整选择器(包括::v-deep伪元素)带入到拼接后的选择器中,你写的.support-category::v-deep { &__subject {} }最终会被编译为非法选择器.support-category::v-deep__subject,自然无法匹配到目标类名。
另外补充一个容易混淆的规则:父组件插槽模板内的DOM元素归属父组件管辖,父组件的scoped样式默认可以直接控制这些元素的样式,不需要使用::v-deep穿透,只有修改子组件自身模板内的元素样式时才需要用到穿透指令。
通用解决方案(完全兼容现有BEM后缀写法)
方案1:拆分穿透与非穿透样式
仅对需要穿透到子组件内部的选择器单独使用::v-deep,不需要穿透的BEM后缀选择器直接写在父级类名下即可,无需包裹在::v-deep块内:
<style lang="scss" scoped> .support-category { /* 插槽内的类,无需穿透,直接用&拼接即可正常生效 */ &__subject { font-size: 18px; font-weight: 700; } &__accordion { font-size: 15px; ul, ol { margin-bottom: 0.75rem; margin-left: 14px; margin-top: 3px; } ul { list-style-type: disc; } ol { list-style-type: decimal; } } .border-bottom { border-bottom: 1px solid color(bg3); } /* 仅要修改v-accordion组件内部的.icon-back样式时,单独加::v-deep穿透 */ ::v-deep .icon-back { font-size: 14px; color: color(text4); } } </style>
方案2:用Sass变量定义基础类名
如果确实需要把多个穿透选择器统一管理,可以先将基础类名定义为Sass变量,用变量拼接后缀,避免&带入::v-deep伪元素:
<style lang="scss" scoped> /* 先定义基础类名变量 */ $base: '.support-category'; #{$base}::v-deep { .icon-back { font-size: 14px; color: color(text4); } .border-bottom { border-bottom: 1px solid color(bg3); } /* 用变量拼接后缀,不会带上::v-deep */ #{$base}__subject { font-size: 18px; font-weight: 700; } #{$base}__accordion { font-size: 15px; ul, ol { margin-bottom: 0.75rem; margin-left: 14px; margin-top: 3px; } ul { list-style-type: disc; } ol { list-style-type: decimal; } } } </style>
以上两种方案改造成本极低,不需要修改现有BEM命名规则,适配你代码库大量使用后缀选择器的场景。
内容的提问来源于stack exchange,提问作者frankaus
相关产品推荐
相关产品推荐

