[Core Team RFC] New SFC macro: defineRender #585
Replies: 9 comments 12 replies
-
This proposal presents a significant opportunity to target React users who are currently migrating to other frameworks. By offering a simple alternative with a lower learning curve, we can provide an attractive option that will help to retain these users. |
Beta Was this translation helpful? Give feedback.
-
While I'm already very familiar with Vue, the React part of my brain that this appeals to find the usage of As such, I would rather see the "alternative" as outlined (which allows a return type) implemented. However, I might propose that we introduce a new script flag to enable this in order to sidestep some of the shortcomings. Maybe:
|
Beta Was this translation helpful? Give feedback.
-
I think this is a great proposal, we came from using Vue 2 with TSX (finally migrated to Vue 3). However everything is in TSX (using defineComponent) in SFC. This change would allow us to progressively migrate our components to setup syntax and convert to templates over time and in stages. |
Beta Was this translation helpful? Give feedback.
-
Or other alternative:We can use <script setup lang="tsx">
import { ref } from 'vue'
const foo = ref('')
export default () => (
<div>{foo.value}</div>
)
</script> |
Beta Was this translation helpful? Give feedback.
-
As someone who wrote a pattern library in vue2 jsx, this would make modernizing and eventually upgrading that library to vue 3 much more straightforward. On that note, I want to request that this be backported to vue 2 (or maybe vue macros already supports this?), as it would allow for incremental migration to a modern syntax. Once the whole library reaches modern syntax in vue 2, the final vue 3 migration is much less daunting. |
Beta Was this translation helpful? Give feedback.
-
Pardon my ignorance, but won't this make two different behaviours between script setup and setup hook? In setup hook one can return a render function directly. The alternative solution mentioned here matches the behaviour of setup hook. |
Beta Was this translation helpful? Give feedback.
-
There're compatibility issues between "typescript-eslint" and using JSX in SFC:
Though they aren't caused by this RFC, such issues can block people to use this macro. |
Beta Was this translation helpful? Give feedback.
-
How does this handle multiple slots? There's this Vue guide, but the syntax seems rather verbose for multiple slots, and I'm hoping that a better macro could simplify the syntax? Note that currently, the Vue Macros |
Beta Was this translation helpful? Give feedback.
-
How would this interact with vapor mode? |
Beta Was this translation helpful? Give feedback.
-
defineRender
macro core#9400Summary
This proposal introduces a new SFC macro called
defineRender
that allows for declaring the render function in<script setup>
without<template>
.Basic example
JSX Element
JSX Render Function
h
FunctionMotivation
<template>
can be limiting in some cases where the render structure of a component needs to be dynamically composed with complex, and sometimes imperative logic.Currently, developers can only use JSX/TSX or raw render functions via
defineComponent
in non-script-setup context. While we have tried to improve the type inference and generic support ofdefineComponent
, it still lacks many other features we have covered in SFCs: HMR, typed emits, typed slots, and higher-level frameworks features like auto imports in Nuxt.You can technically use render functions in
<script setup>
via therender
option withdefineOptions
- but due to the scope restrictions ofdefineOptions
, code insiderender()
won't have access to setup scope variables.defineRender
fills this gap: it allows developers to use JSX/TSX render functions in<script setup>
when needed, while keeping the same consistent access to all the SFC features.Detailed design
<script setup>
only feature.defineRender
, and it's disabled by default.<template>
. If it does, an error will be thrown.<div />
=>() => <div />
)h
functions.Macro Signature
Drawbacks
Alternatives
Return Statement
Allows a return statement in
<script setup>
Compared to
defineRender
macro:return
statement has unclear semantics.return
can be written more than once can could cause losing reactivity, but indefineRender
it can only called once.<script setup>
but the return statement is not.See more at #585 (comment)
Export Default Statement
Also implemented in Vue Macros.
Compared to the
defineRender
and return statement:export default
statements in both<script>
&<script setup>
could make developers confused.See more at #585 (comment)
Adoption strategy
It's an opt-in feature and is disabled by default now.
Unresolved questions
N/A
Appendix
Existing Implementation
defineRender
is already available in Vue Macros.Beta Was this translation helpful? Give feedback.
All reactions