Sfoglia il codice sorgente

fix(runtime-dom): fix behavior regression for v-show + style display binding

fix #4768
Evan You 4 anni fa
parent
commit
3f38d599f5

+ 8 - 0
packages/runtime-dom/__tests__/patchStyle.spec.ts

@@ -68,6 +68,14 @@ describe(`runtime-dom: style patching`, () => {
     expect(el.style.width).toBe('0px')
   })
 
+  it('should remove style attribute on falsy value', () => {
+    const el = document.createElement('div')
+    el.style.cssText = 'color: red;'
+    patchProp(el as any, 'style', {}, null)
+    expect(el.hasAttribute('style')).toBe(false)
+    expect(el.style.cssText).toBe('')
+  })
+
   // JSDOM doesn't support custom properties on style object so we have to
   // mock it here.
   function mockElementWithStyle() {

+ 17 - 14
packages/runtime-dom/src/modules/style.ts

@@ -5,14 +5,8 @@ type Style = string | Record<string, string | string[]> | null
 
 export function patchStyle(el: Element, prev: Style, next: Style) {
   const style = (el as HTMLElement).style
-  const currentDisplay = style.display
-  if (!next) {
-    el.removeAttribute('style')
-  } else if (isString(next)) {
-    if (prev !== next) {
-      style.cssText = next
-    }
-  } else {
+  const isCssString = isString(next)
+  if (next && !isCssString) {
     for (const key in next) {
       setStyle(style, key, next[key])
     }
@@ -23,12 +17,21 @@ export function patchStyle(el: Element, prev: Style, next: Style) {
         }
       }
     }
-  }
-  // indicates that the `display` of the element is controlled by `v-show`,
-  // so we always keep the current `display` value regardless of the `style` value,
-  // thus handing over control to `v-show`.
-  if ('_vod' in el) {
-    style.display = currentDisplay
+  } else {
+    const currentDisplay = style.display
+    if (isCssString) {
+      if (prev !== next) {
+        style.cssText = next as string
+      }
+    } else if (prev) {
+      el.removeAttribute('style')
+    }
+    // indicates that the `display` of the element is controlled by `v-show`,
+    // so we always keep the current `display` value regardless of the `style`
+    // value, thus handing over control to `v-show`.
+    if ('_vod' in el) {
+      style.display = currentDisplay
+    }
   }
 }