fix: correct Vue ref auto-unwrapping in slot components #5378
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Fixed Vue's auto-unwrapping behavior for exposed template refs in slot components, resolving slot registration failures.
Changes
defineExpose
in InputSlot.vue and OutputSlot.vueReview Focus
The key fix addresses Vue's automatic ref unwrapping when a child component exposes a ref through
defineExpose
. The parent was incorrectly treating the exposed value as aRef<HTMLElement>
and calling.value
, but Vue already unwraps it toHTMLElement
.Technical Details
Exact Issue
SlotConnectionDot.vue
exposes a template ref withdefineExpose({ slotElRef })
, whereslotElRef
comes fromuseTemplateRef('slot-el')
defineExpose
, Vue auto-unwraps it on the parent component instance proxyRef
and read.value
(double-unwrapping), which producedundefined
at runtimeslotElRef
stayed null anduseDomSlotRegistration
had no element to measure/register, breaking slot hit-testing/linkingWhat Changed
Before:
connectionDotRef: ref<{ slotElRef: Ref<HTMLElement> }>()
watch(connectionDotRef, ...)
and accessednewValue.slotElRef.value
After:
connectionDotRef: ref<ComponentPublicInstance<{ slotElRef: HTMLElement | undefined }> | null>()
watchEffect(() => { slotElRef.value = connectionDotRef.value?.slotElRef || null })
Why It Works
.value
on an already unwrapped HTMLElementwatchEffect
reruns when the child's exposedslotElRef
appears (after mount), whereas the oldwatch
only reacted to component ref assignmentWith these fixes,
slotElRef
is reliably populated,useDomSlotRegistration
can measure and register slot positions, and slot hit-testing/connection logic works as intended.┆Issue is synchronized with this Notion page by Unito