]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(compiler-ssr): fix SSR issue when dynamic and static class co-exist (#2354)
authorMathieu TUDISCO <oss@mathieutu.dev>
Tue, 13 Oct 2020 20:25:15 +0000 (22:25 +0200)
committerGitHub <noreply@github.com>
Tue, 13 Oct 2020 20:25:15 +0000 (16:25 -0400)
packages/compiler-ssr/__tests__/ssrElement.spec.ts
packages/compiler-ssr/src/transforms/ssrInjectCssVars.ts
packages/compiler-ssr/src/transforms/ssrTransformElement.ts
packages/server-renderer/__tests__/renderToString.spec.ts

index 55eaa50647c587147615bd928365ee217d082ab0..30e75e36f2b10f0cca210b44095ca7fb8e0dbd34 100644 (file)
@@ -112,6 +112,15 @@ describe('ssr: element', () => {
       `)
     })
 
+    test('v-bind:class + static class', () => {
+      expect(getCompiledString(`<div :class="bar" class="foo"></div>`))
+        .toMatchInlineSnapshot(`
+        "\`<div class=\\"\${
+            _ssrRenderClass([_ctx.bar, \\"foo\\"])
+          }\\"></div>\`"
+      `)
+    })
+
     test('v-bind:style', () => {
       expect(getCompiledString(`<div id="foo" :style="bar"></div>`))
         .toMatchInlineSnapshot(`
index 0e6540c3b669f1261bdaf9b9c9eec05abb60906e..c848598a286727b8d405b26525ef19e4702d2c35 100644 (file)
@@ -15,8 +15,8 @@ export const ssrInjectCssVars: NodeTransform = (node, context) => {
     return
   }
 
-  // _cssVars is initailized once per render function
-  // the code is injected in ssrCodegenTrasnform when creating the
+  // _cssVars is initialized once per render function
+  // the code is injected in ssrCodegenTransform when creating the
   // ssr transform context
   if (node.type === NodeTypes.ROOT) {
     context.identifiers._cssVars = 1
index e2f2ed8de847c7361b50faf67e1713417b1e21a5..e036671fcda0c73f20614cb08279a86936160cf3 100644 (file)
@@ -324,9 +324,10 @@ function removeStaticBinding(
   tag: TemplateLiteral['elements'],
   binding: string
 ) {
-  const i = tag.findIndex(
-    e => typeof e === 'string' && e.startsWith(` ${binding}=`)
-  )
+  const regExp = new RegExp(`^ ${binding}=".+"$`)
+
+  const i = tag.findIndex(e => typeof e === 'string' && regExp.test(e))
+
   if (i > -1) {
     tag.splice(i, 1)
   }
index 25704eeee4668a2fa94f9786cdc80e3f7647ef1e..a7756a89e6b667f8a7cb76dc4d1fcdeb290f97fa 100644 (file)
@@ -142,6 +142,24 @@ describe('ssr: renderToString', () => {
       )
     })
 
+    test('template components with dynamic class attribute after static', async () => {
+      const app = createApp({
+        template: `<div><div class="child" :class="'dynamic'"></div></div>`
+      })
+      expect(await renderToString(app)).toBe(
+        `<div><div class="dynamic child"></div></div>`
+      )
+    })
+
+    test('template components with dynamic class attribute before static', async () => {
+      const app = createApp({
+        template: `<div><div :class="'dynamic'" class="child"></div></div>`
+      })
+      expect(await renderToString(app)).toBe(
+        `<div><div class="dynamic child"></div></div>`
+      )
+    })
+
     test('mixing optimized / vnode / template components', async () => {
       const OptimizedChild = {
         props: ['msg'],