]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(runtime-dom): ensure v-show respects display value set via v-bind (#10161)
authorDoctor Wu <44631608+Doctor-wu@users.noreply.github.com>
Wed, 7 Feb 2024 04:54:21 +0000 (12:54 +0800)
committerGitHub <noreply@github.com>
Wed, 7 Feb 2024 04:54:21 +0000 (12:54 +0800)
close #10151

packages/runtime-dom/__tests__/directives/vShow.spec.ts
packages/runtime-dom/src/directives/vShow.ts
packages/runtime-dom/src/modules/style.ts

index 70b69f2df1c10050e3c42547a49d78511739752a..0c299b51b9ad1274c763a3360d23c242528a833c 100644 (file)
@@ -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('')
+  })
 })
index 2ab25136e74a7ccbd7fa3c2523298f82f1072f84..d8aab92e71bebd6ee02b2178e25675656eb25bca 100644 (file)
@@ -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)
index 6341c8a120e0690270e8c64dc698f4c6d094105e..ef2c55dbbf7b14745cb801936bfdf33822ff8c45 100644 (file)
@@ -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
   }
 }