VuReact 是一个能将 Vue 3 代码编译为标准、可维护 React 代码的工具。今天就带大家直击核心Vue 作用域样式中的穿透选择器:deep/:global/:slotted经过 VuReact 编译后会变成什么样的 React 代码前置约定为避免示例代码冗余导致理解偏差先明确两个小约定文中 Vue / React 代码均为核心逻辑简写省略完整组件包裹、无关配置等内容默认读者已熟悉样式:deep/:global/:slotted的用法。编译对照:global()声明全局样式:global()用于在 scoped 样式中声明一段不受作用域限制的全局样式。VuReact 的处理方式移除:global()包装保留内部选择器原样输出。Vue 代码!-- Component.vue --templatedivclasscomponentdivclassglobal-class全局类/div/div/templatestylescoped.component{:global(.global-class){color:green;}}/styleVuReact 编译后 CSS/* component-abc123.css */.component[data-css-abc123]{.global-class{color:green;}}从示例可以看到:global(...)被完全移除内部的选择器照常展开且不添加 scope 属性。这样.global-class就是一个全局可用的样式类。:deep()样式穿透:deep()是 scoped 样式中最常用的穿透选择器用于让父组件的样式能够影响子组件内部的元素。VuReact 的处理策略是将:deep(...)左侧的选择器加上 scope右侧:deep内部的选择器保持原样。在嵌套规则中使用:deep()Vue 代码!-- Component.vue --templatedivclasscomponentdivclassnested-component深层嵌套组件/div/div/templatestylescoped.component{:deep(.nested-component){background:yellow;}}/styleVuReact 编译后 CSS/* component-abc123.css */.component[data-css-abc123]{ .nested-component{background:yellow;}}从示例可以看到在嵌套规则中:deep()左侧是.component加 scope右侧.nested-component不加 scope。在单行规则中使用:deep():deep()也可以在非嵌套的单行规则中使用左侧部分仍然被 scoped。Vue 代码stylescoped.parent :deep(.btn){color:red;}/styleVuReact 编译后 CSS.parent[data-css-abc123] .btn{color:red;}:deep()紧贴选择器Vue 代码stylescoped.parent:deep(.btn){color:red;}/styleVuReact 编译后 CSS.parent[data-css-abc123] .btn{color:red;}带组合器的:deep()Vue 代码stylescoped.parent :deep(.btn){color:red;}/styleVuReact 编译后 CSS.parent[data-css-abc123] .btn{color:red;}:deep()作为选择器起始当:deep()位于选择器最左侧时无左侧部分VuReact 会直接用[scopeId]作为左侧。Vue 代码stylescoped:deep(.btn){color:red;}/styleVuReact 编译后 CSS[data-css-abc123] .btn{color:red;}处理逻辑左侧为空时用[data-css-abc123]自身作为 scoped 占位。:deep()展开逗号选择器:deep()内部可以包含多个逗号分隔的选择器VuReact 会逐一展开。Vue 代码stylescoped.a :deep(.x, .y){color:red;}/styleVuReact 编译后 CSS.a[data-css-abc123] .x, .a[data-css-abc123] .y{color:red;}从示例可以看到:deep(.x, .y)被展开为两个独立的选择器.x和.y各自与左侧.a[data-css-abc123]拼接。4.:slotted()插槽样式:slotted()用于为插槽传入的内容设置样式VuReact 当前的处理方式是简单解包。Vue 代码stylescoped.component{:slotted(.slotted-content){display:flex;}}/styleVuReact 编译后 CSS.component[data-css-abc123]{.slotted-content{display:flex;}}从示例可以看到:slotted(...)被移除内部选择器.slotted-content保留但不加 scope。完整的:slotted()语义支持仍在解决中。复杂选择器共存在一个组件中:global、:deep、:slotted可以与标准 scoped 选择器以及伪类:hover、::before等混合使用。Vue 代码stylescoped.component{:hover{opacity:0.8;}.active{font-weight:bold;}:global(.global-class){color:green;}:deep(.nested-component){background:yellow;}:slotted(.slotted-content){display:flex;}:not(:first-child){margin-top:20px;}:nth-child(2n){background:#f0f0f0;}::before{content:→;}::placeholder{color:gray;}}/styleVuReact 编译后 CSS.component[data-css-abc123]{:hover{opacity:0.8;}.active{font-weight:bold;}.global-class{color:green;} .nested-component{background:yellow;}.slotted-content{display:flex;}:not(:first-child){margin-top:20px;}:nth-child(2n){background:#f0f0f0;}::before{content:→;}::placeholder{color:gray;}}共处规则选择器类型行为scope 注入标准选择器尾部追加[data-css-xxx]✅伪类/属性选择器保持原样插入 scope 在其之前✅:global(...)移除包装内部不加 scope✅:deep(...)左侧加 scope内部不加✅:slotted(...)移除包装内部不加 scope⚠️待完善编译策略总结VuReact 的作用域样式穿透选择器编译策略展示了完整的 scoped 选择器转换能力:global()转换移除:global(...)包装内部选择器按全局样式输出不加 scope:deep()转换将选择器按:deep(...)位置切割左侧加 scope内部保持穿透能力支持嵌套、组合器、逗号展开等复杂场景:slotted()转换移除:slotted(...)包装内部选择器保持原样完整语义实现 WIP伪类兼容:hover、::before、:not()、:nth-child()等伪类保持原样scope 只插入在伪类之前嵌套兼容与 SCSS/Less 的嵌套语法协作良好支持的穿透选择器选择器状态说明:deep()✅ 完整支持左侧 scoped 右侧穿透:global()✅ 完整支持移除包装全局样式:slotted()⚠️ 部分支持解包处理完整语义待完善VuReact 的编译策略确保了从 Vue 到 React 的平滑迁移。编译后的 CSS 选择器既保持了 Vue scoped 样式的作用域隔离语义又能通过:deep()和:global()灵活控制样式穿透范围让迁移后的应用保持完整的 scoped 样式能力。 相关资源VuReact 官方文档语义编译对照总览Githubhttps://github.com/vureact-js/core 继续阅读上一篇样式语言支持下一篇《VuReact 全合集Vue 转 React 语义编译对照指南附官网文档》✨ 如果你觉得本文对你理解 VuReact 有帮助欢迎点赞、收藏、关注