Subscribe on changes!

Add and document defineFunctionalComponent

avatar
Jan 26th 2023

What problem does this feature solve?

Defining type-safe functional components is more difficult than normal components, because:

  • The FunctionalComponent type is undocumented
  • There is no defineFunctionalComponent helper

What does the proposed API look like?

// MyComponent.ts
import { h, defineFunctionalComponent } from 'vue'

export type MyComponentProps = { ... }
export type MyComponentEmits = { ... }

export default defineFunctionalComponent<MyComponentProps, MyComponentEmits>(
  (props, ctx) => h(...)
)
avatar
Feb 3rd 2023

Is that what you are looking for?

export default defineComonent<Props, Emits>((props, ctx) => () => h(...))

Note that you must pass a setup function that returns render function. Actually, I'm not quite sure about Emits generic structure. Maybe props like onSomething would be more suitable for you, since all emits are actually props in on<event_name> format. 🤔

See also: https://v3-migration.vuejs.org/breaking-changes/functional-components.html#_3-x-syntax

avatar
Feb 4th 2023

Close but not quite—defineComponent accepts a setup function that can return a render function. It returns a full component with its own lifecycle.

defineFunctionalComponent should accept the render function itself, not a setup function, and it should be a no-op (it should just return the render function, which renders a functional component with no lifecycle of its own)

defineFunctionalComponent is only needed for easy type safety, it doesn't do anything else.

https://vuejs.org/guide/extras/render-function.html#functional-components

avatar
Apr 13th 2023

What about slots passed to the functional components? I feel that the API should also cover that, like so:

// MyComponent.ts
import { h, defineFunctionalComponent } from 'vue'

export type MyComponentProps = { ... }
export type MyComponentEmits = { ... }
export type MyComponentSlots = { ... }

export default defineFunctionalComponent<MyComponentProps, MyComponentEmits, MyComponentSlots>(
  (props, ctx) => h(...)
)