import type { NodeRef } from '../../src/apiTemplateRef'
import {
+ child,
createComponent,
+ createDynamicComponent,
createFor,
createIf,
createSlot,
createTemplateRefSetter,
+ defineVaporComponent,
insert,
renderEffect,
template,
useTemplateRef,
watchEffect,
} from '@vue/runtime-dom'
-import { setElementText } from '../../src/dom/prop'
+import { setElementText, setText } from '../../src/dom/prop'
+import type { VaporComponent } from '../../src/component'
const define = makeRender()
expect(r!.value).toBe(n)
})
+ test('work with dynamic component', async () => {
+ const Child = defineVaporComponent({
+ setup(_, { expose }) {
+ const msg = ref('one')
+ expose({ setMsg: (m: string) => (msg.value = m) })
+ const n0 = template(`<div> </div>`)() as any
+ const x0 = child(n0) as any
+ renderEffect(() => setText(x0, msg.value))
+ return n0
+ },
+ })
+
+ const views: Record<string, VaporComponent> = { child: Child }
+ const view = ref('child')
+ const refKey = ref<any>(null)
+
+ const { html } = define({
+ setup() {
+ const setRef = createTemplateRefSetter()
+ const n0 = createDynamicComponent(() => views[view.value]) as any
+ setRef(n0, refKey)
+ return n0
+ },
+ }).render()
+
+ expect(html()).toBe('<div>one</div><!--dynamic-component-->')
+ expect(refKey.value).toBeDefined()
+
+ refKey.value.setMsg('changed')
+ await nextTick()
+ expect(html()).toBe('<div>changed</div><!--dynamic-component-->')
+ })
+
// TODO: can not reproduce in Vapor
// // #2078
// test('handling multiple merged refs', async () => {
isString,
remove,
} from '@vue/shared'
+import { DynamicFragment } from './block'
export type NodeRef = string | Ref | ((ref: Element) => void)
export type RefEl = Element | VaporComponentInstance
if (!instance || instance.isUnmounted) return
const setupState: any = __DEV__ ? instance.setupState || {} : null
- const refValue = isVaporComponent(el) ? getExposed(el) || el : el
+ const refValue = getRefValue(el)
const refs =
instance.refs === EMPTY_OBJ ? (instance.refs = {}) : instance.refs
}
return ref
}
+
+const getRefValue = (el: RefEl) => {
+ if (isVaporComponent(el)) {
+ return getExposed(el) || el
+ } else if (el instanceof DynamicFragment) {
+ return getRefValue(el.nodes as RefEl)
+ }
+ return el
+}