Просмотр исходного кода

fix(cssVars): cssVar names should be double-escaped when generating code for ssr (#8824)

close #7823
edison 2 лет назад
Родитель
Сommit
5199a12f88

+ 3 - 1
packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap

@@ -1003,10 +1003,12 @@ export default {
   setup(__props) {
 
         const count = ref(0)
+        const style = { color: 'red' }
         
 return (_ctx, _push, _parent, _attrs) => {
   const _cssVars = { style: {
-  \\"--xxxxxxxx-count\\": (count.value)
+  \\"--xxxxxxxx-count\\": (count.value),
+  \\"--xxxxxxxx-style\\\\\\\\.color\\": (style.color)
 }}
   _push(\`<!--[--><div\${
     _ssrRenderAttrs(_cssVars)

+ 3 - 0
packages/compiler-sfc/__tests__/compileScript.spec.ts

@@ -778,6 +778,7 @@ describe('SFC compile <script setup>', () => {
         <script setup>
         import { ref } from 'vue'
         const count = ref(0)
+        const style = { color: 'red' }
         </script>
         <template>
           <div>{{ count }}</div>
@@ -785,6 +786,7 @@ describe('SFC compile <script setup>', () => {
         </template>
         <style>
         div { color: v-bind(count) }
+        span { color: v-bind(style.color) }
         </style>
         `,
         {
@@ -799,6 +801,7 @@ describe('SFC compile <script setup>', () => {
       expect(content).toMatch(`ssrInterpolate`)
       expect(content).not.toMatch(`useCssVars`)
       expect(content).toMatch(`"--${mockId}-count": (count.value)`)
+      expect(content).toMatch(`"--${mockId}-style\\\\.color": (style.color)`)
       assertCode(content)
     })
 

+ 4 - 2
packages/compiler-sfc/src/script/utils.ts

@@ -121,6 +121,8 @@ export function getEscapedPropName(key: string) {
 
 export const cssVarNameEscapeSymbolsRE = /[ !"#$%&'()*+,./:;<=>?@[\\\]^`{|}~]/g
 
-export function getEscapedCssVarName(key: string) {
-  return key.replace(cssVarNameEscapeSymbolsRE, s => `\\${s}`)
+export function getEscapedCssVarName(key: string, doubleEscape: boolean) {
+  return key.replace(cssVarNameEscapeSymbolsRE, s =>
+    doubleEscape ? `\\\\${s}` : `\\${s}`
+  )
 }

+ 11 - 3
packages/compiler-sfc/src/style/cssVars.ts

@@ -22,17 +22,25 @@ export function genCssVarsFromList(
 ): string {
   return `{\n  ${vars
     .map(
-      key => `"${isSSR ? `--` : ``}${genVarName(id, key, isProd)}": (${key})`
+      key =>
+        `"${isSSR ? `--` : ``}${genVarName(id, key, isProd, isSSR)}": (${key})`
     )
     .join(',\n  ')}\n}`
 }
 
-function genVarName(id: string, raw: string, isProd: boolean): string {
+function genVarName(
+  id: string,
+  raw: string,
+  isProd: boolean,
+  isSSR = false
+): string {
   if (isProd) {
     return hash(id + raw)
   } else {
     // escape ASCII Punctuation & Symbols
-    return `${id}-${getEscapedCssVarName(raw)}`
+    // #7823 need to double-escape in SSR because the attributes are rendered
+    // into an HTML string
+    return `${id}-${getEscapedCssVarName(raw, isSSR)}`
   }
 }