Skip to content

Fields vs. Controls

As of Formwerk v0.14.0, we shipped a version of each composable that uses the use***Control name. For example: useTextField and useTextControl.

This was done to allow for a more precise separation between the field and the control that are often needed in UI libraries that deal with forms, mainly to dry the common parts of a field like labels, descriptions, and error messages.

We will publish a guide on how to build a UI library that uses these new composables, but for first-party code you should continue using the use***Field composables. There isn’t much difference between the two, both can be used within forms and both can be validated.

Under the hood, both use***Field and use***Control have a very similar API when it comes to props and return values. However, the use***Control composables prefer to find a parent field context to use its values and state.

On the other hand, the use***Field composables are not bound to a parent field context and always create their own context.

This minor difference has a couple of implications when designing a form component API.

If you want to build components that are self-contained as field components, you should use the use***Field composables. The documentation and all its example follow this pattern as it is the most common for first-party code. In other words, this is the recommended approach for building your own form components.

Your components’ usage will look like this:

<TextField v-model="value" label="My Field" />

The key features of this design are:

  • Single component tags for most of the cases.
  • Less code to “use”, more code to “write”.
  • No need to worry about the context of the field.

If you want to build a component system that allows for more flexibility and composition, you should use the use***Control composables.

You must make use of useFormField to create a field context that will be used by the control components. It is up to you to manage that properly, but if you don’t then the control composables will create their own context and pretty much behave like a field composable.

In terms of usage, it will look like this:

<FormField name="my-field">
<TextControl v-model="value" label="My Field" />
</FormField>

The key features of this design are:

  • More code to “use”, less code to “write”.
  • More flexibility and composition between similar controls.
  • You need to be careful about field contexts created by <FormField>.