Explorar el Código

fix(compile-sfc): auto add nesting combinators for ::v-deep in scoped CSS

daiwei hace 1 año
padre
commit
6f0f944d83

+ 12 - 0
packages/compiler-sfc/__tests__/compileStyle.spec.ts

@@ -140,6 +140,18 @@ color: red
       }
       }"
     `)
+    expect(compileScoped(`.foo { :deep(.bar) { color: red; }}`))
+      .toMatchInlineSnapshot(`
+        ".foo {
+        &[data-v-test] .bar { color: red;
+        }}"
+      `)
+    expect(compileScoped(`.foo { & :deep(.bar) { color: red; }}`))
+      .toMatchInlineSnapshot(`
+        ".foo {
+        &[data-v-test] .bar { color: red;
+        }}"
+      `)
   })
 
   test('::v-slotted', () => {

+ 23 - 0
packages/compiler-sfc/src/style/pluginScoped.ts

@@ -133,6 +133,29 @@ function rewriteSelector(
             selector.insertAfter(last, ss)
             last = ss
           })
+
+          // if css nesting is used, we need to insert a nesting combinator
+          // before the ::v-deep node
+          // .foo { ::v-deep(.bar) } -> .foo { &[xxxxxxx] .bar }
+          const isNestedRule = rule.parent && rule.parent.type === 'rule'
+          if (isNestedRule && n.parent) {
+            let hasNestingCombinator = false
+            let index = n.parent.index(n) - 1
+            while (index >= 0) {
+              const prev = n.parent.at(index)
+              if (!prev) break
+              if (prev.type === 'nesting') {
+                hasNestingCombinator = true
+                break
+              }
+              index--
+            }
+            if (!hasNestingCombinator) {
+              node = selectorParser.nesting()
+              selector.insertBefore(n, node)
+            }
+          }
+
           // insert a space combinator before if it doesn't already have one
           const prev = selector.at(selector.index(n) - 1)
           if (!prev || !isSpaceCombinator(prev)) {