2
0
Эх сурвалжийг харах

fix(runtime-vapor): apply v-show to vdom child (#13767)

close #13765
edison 8 сар өмнө
parent
commit
def21b6780

+ 32 - 0
packages/runtime-vapor/__tests__/vdomInterop.spec.ts

@@ -11,6 +11,7 @@ import {
 import { makeInteropRender } from './_utils'
 import {
   applyTextModel,
+  applyVShow,
   child,
   createComponent,
   defineVaporComponent,
@@ -113,6 +114,37 @@ describe('vdomInterop', () => {
     })
   })
 
+  describe('v-show', () => {
+    test('apply v-show to vdom child', async () => {
+      const VDomChild = {
+        setup() {
+          return () => h('div')
+        },
+      }
+
+      const show = ref(false)
+      const VaporChild = defineVaporComponent({
+        setup() {
+          const n1 = createComponent(VDomChild as any)
+          applyVShow(n1, () => show.value)
+          return n1
+        },
+      })
+
+      const { html } = define({
+        setup() {
+          return () => h(VaporChild as any)
+        },
+      }).render()
+
+      expect(html()).toBe('<div style="display: none;"></div>')
+
+      show.value = true
+      await nextTick()
+      expect(html()).toBe('<div style=""></div>')
+    })
+  })
+
   describe('slots', () => {
     test('basic', () => {
       const VDomChild = defineComponent({

+ 13 - 3
packages/runtime-vapor/src/directives/vShow.ts

@@ -6,7 +6,7 @@ import {
 } from '@vue/runtime-dom'
 import { renderEffect } from '../renderEffect'
 import { isVaporComponent } from '../component'
-import { type Block, DynamicFragment } from '../block'
+import { type Block, DynamicFragment, VaporFragment } from '../block'
 import { isArray } from '@vue/shared'
 
 export function applyVShow(target: Block, source: () => any): void {
@@ -24,6 +24,12 @@ export function applyVShow(target: Block, source: () => any): void {
       update.call(target, render, key)
       setDisplay(target, source())
     }
+  } else if (target instanceof VaporFragment && target.insert) {
+    const insert = target.insert
+    target.insert = (parent, anchor) => {
+      insert.call(target, parent, anchor)
+      setDisplay(target, source())
+    }
   }
 
   renderEffect(() => setDisplay(target, source()))
@@ -33,12 +39,16 @@ function setDisplay(target: Block, value: unknown): void {
   if (isVaporComponent(target)) {
     return setDisplay(target, value)
   }
-  if (isArray(target) && target.length === 1) {
-    return setDisplay(target[0], value)
+  if (isArray(target)) {
+    if (target.length === 0) return
+    if (target.length === 1) return setDisplay(target[0], value)
   }
   if (target instanceof DynamicFragment) {
     return setDisplay(target.nodes, value)
   }
+  if (target instanceof VaporFragment && target.insert) {
+    return setDisplay(target.nodes, value)
+  }
   if (target instanceof Element) {
     const el = target as VShowElement
     if (!(vShowOriginalDisplay in el)) {

+ 2 - 0
packages/runtime-vapor/src/vdomInterop.ts

@@ -216,6 +216,8 @@ function createVDOMComponent(
         parentInstance as any,
       )
     }
+
+    frag.nodes = vnode.el as Block
   }
 
   frag.remove = unmount