Przeglądaj źródła

fix(runtime-dom): ensure v-show respects display value set via v-bind (#10161)

close #10151
Doctor Wu 2 lat temu
rodzic
commit
9b19f09121

+ 65 - 0
packages/runtime-dom/__tests__/directives/vShow.spec.ts

@@ -211,4 +211,69 @@ describe('runtime-dom: v-show directive', () => {
     await nextTick()
     expect($div.style.display).toEqual('')
   })
+
+  // #10151
+  test('should respect the display value when v-show value is true', async () => {
+    const isVisible = ref(false)
+    const useDisplayStyle = ref(true)
+    const compStyle = ref({
+      display: 'none',
+    })
+    const withoutDisplayStyle = {
+      margin: '10px',
+    }
+
+    const Component = {
+      setup() {
+        return () => {
+          return withVShow(
+            h('div', {
+              style: useDisplayStyle.value
+                ? compStyle.value
+                : withoutDisplayStyle,
+            }),
+            isVisible.value,
+          )
+        }
+      },
+    }
+    render(h(Component), root)
+
+    const $div = root.children[0]
+
+    expect($div.style.display).toEqual('none')
+
+    isVisible.value = true
+    await nextTick()
+    expect($div.style.display).toEqual('none')
+
+    compStyle.value.display = 'block'
+    await nextTick()
+    expect($div.style.display).toEqual('block')
+
+    compStyle.value.display = 'inline-block'
+    await nextTick()
+    expect($div.style.display).toEqual('inline-block')
+
+    isVisible.value = false
+    await nextTick()
+    expect($div.style.display).toEqual('none')
+
+    isVisible.value = true
+    await nextTick()
+    expect($div.style.display).toEqual('inline-block')
+
+    useDisplayStyle.value = false
+    await nextTick()
+    expect($div.style.display).toEqual('')
+    expect(getComputedStyle($div).display).toEqual('block')
+
+    isVisible.value = false
+    await nextTick()
+    expect($div.style.display).toEqual('none')
+
+    isVisible.value = true
+    await nextTick()
+    expect($div.style.display).toEqual('')
+  })
 })

+ 1 - 1
packages/runtime-dom/src/directives/vShow.ts

@@ -22,7 +22,7 @@ export const vShow: ObjectDirective<VShowElement> & { name?: 'show' } = {
     }
   },
   updated(el, { value, oldValue }, { transition }) {
-    if (!value === !oldValue) return
+    if (!value === !oldValue && el.style.display === el[vShowOldKey]) return
     if (transition) {
       if (value) {
         transition.beforeEnter(el)

+ 1 - 0
packages/runtime-dom/src/modules/style.ts

@@ -38,6 +38,7 @@ export function patchStyle(el: Element, prev: Style, next: Style) {
   // so we always keep the current `display` value regardless of the `style`
   // value, thus handing over control to `v-show`.
   if (vShowOldKey in el) {
+    el[vShowOldKey] = style.display
     style.display = currentDisplay
   }
 }