-
Notifications
You must be signed in to change notification settings - Fork 8
Open
Description
Related issue: vuejs/composition-api#91
The babel-sugar-setup-ref
plugin only works inside the setup()
function. This is problematic because when common logic is extracted into composable units in other functions, code can break silently, and without having any visible functional differences to working code.
E.g. this works:
export default createComponent({
setup() {
const visibilitySensorEl = ref(null);
const isOnScreen = computed(() => visibilitySensorEl != null && isElementVisible(visibilitySensorEl));
return () => (
<div>
<div ref={visibilitySensorEl} />
{isOnScreen && renderContent()}
</div>
);
}
})
But if you try to extract the logic, visibilitySensorEl
stays null
and nothing works:
const useVisibilitySensor = () => {
const visibilitySensorEl = ref(null);
return {
renderVisibilitySensor: () => <div ref={visibilitySensorEl} />,
isOnScreen: computed(() => visibilitySensorEl != null && isElementVisible(visibilitySensorEl))
}
}
export default createComponent({
setup() {
const { renderVisibilitySensor, isOnScreen } = useVisibilitySensor();
return () => (
<div>
{renderVisibilitySensor()}
{isOnScreen && renderContent()}
</div>
);
}
})
The big problem is that this difference is completely invisible to the developer - no compile errors, no console warnings, no obvious difference in code. This took me hours to debug, and I imagine plenty of other developers will also hit this case.
There are a few possible ways I can see this could be fixed:
- Rewrite
ref={something}
everywhere, not just in thesetup
method - Emit a compile-time warning when
ref={something}
is seen outside of thesetup
method - Instead of detecting and modifying
ref={}
at compile time, wrap the return value ofsetup()
with a function that walks the returned VNode tree and replacesref
values at run time - Instead of detecting and modifying
ref={}
at compile time, wraph
/createElement
so that it automatically convertsref
s
b12f, wcldyx and iwash0120
Metadata
Metadata
Assignees
Labels
No labels