Skip to content
beginner Phase 8 · Forms and Validation

Checkbox and Radio Bindings

Bind grouped checkboxes to arrays and radios to a single value.

40m
0 problems
Topic Progress 0%

Checkbox and Radio Bindings: Core Concepts

The model shape follows the control

Checkboxes and radios represent different kinds of choices, so their v-model values should have different shapes. A single checkbox commonly represents a boolean: unchecked is false and checked is true. A checkbox group represents a set of independently selectable values, so Vue uses an array model and adds or removes each checked control's value. A radio group represents one choice among alternatives, so all radio controls share one model and each writes its own value when selected.

<script setup>
import { reactive } from 'vue'

const preferences = reactive({
  productUpdates: false,
  channels: [],
  plan: 'starter',
})
</script>

<template>
  <fieldset>
    <legend>Notification channels</legend>
    <label><input v-model="preferences.channels" type="checkbox" value="email"> Email</label>
    <label><input v-model="preferences.channels" type="checkbox" value="sms"> SMS</label>
  </fieldset>

  <label><input v-model="preferences.productUpdates" type="checkbox"> Product updates</label>

  <fieldset>
    <legend>Plan</legend>
    <label><input v-model="preferences.plan" type="radio" value="starter"> Starter</label>
    <label><input v-model="preferences.plan" type="radio" value="team"> Team</label>
  </fieldset>
</template>

The array initializer is important. It tells both Vue and readers that multiple values are expected, and it gives the template a predictable value before the user interacts. If the choices come from an API, initialize the array first and populate the option list separately. Do not infer selection from whether a DOM node happens to be checked; the reactive model is the state to save, validate, and test.

Give each choice a stable value that matches the data contract. Labels are for people and may change with localization or copy edits; values are for code and should remain stable. If a checkbox omits an explicit value, the browser's default value is not a useful domain identifier. For radio groups, make values unique and ensure all choices that belong together share one model. A radio group with no selected option can use null as its initial value and require the user to choose deliberately.

Boolean alternatives and dynamic values

Vue supports true-value and false-value for a single checkbox when a domain uses values other than booleans. For example, an older API may represent an enabled flag as the strings enabled and disabled. Those attributes change the values assigned by v-model; they do not turn a multi-checkbox group into a scalar. Prefer a boolean inside application state and convert at the API boundary when possible, because booleans are easier to reason about in conditions and computed values.

The checkbox-group model may contain strings, numbers, or bound values. Use a bound value when the application needs a non-string value, and keep the model type consistent across the list. A frequent defect is comparing a string id from an option against a numeric id in the form model; the rendered choice may look correct initially but membership checks and payload validation then disagree. Normalize ids when data enters the form rather than sprinkling conversions across the template.

Accessibility and form semantics

Use fieldset and legend to expose a group name, and associate each input with a visible label. Do not make the only clickable target a tiny control if the label can be associated with it. The group structure is especially important for radios because the question applies to the set, not to any one option. Keep keyboard behavior native: users should be able to tab into a group and move through radio choices with arrow keys.

Initialize defaults intentionally. A preselected radio must be a valid default for the user and product policy; otherwise null avoids silently recording a choice. For consent, do not preselect a box that represents agreement if that would misstate the user's action. A default notification preference should be visible and changeable. In all cases, the payload should distinguish an untouched choice from an explicit opt-out when the business rule requires that distinction.

Think of these controls as typed data capture: boolean for one on/off decision, array for many independent selections, and scalar for one-of-many selection. That small distinction prevents accidental overwrites, makes validation direct, and keeps the form payload understandable.

Checkbox and Radio Bindings: Practice

Construct and inspect the selection model

Build a settings form with one consent flag, a collection of notification channels, and one delivery frequency. Keep the state in a reactive object and bind each native control to the property whose type matches its behavior. Use explicit values for every member of a group; the selected labels should never be the accidental API contract.

const settings = reactive({
  consent: false,
  channels: [],
  frequency: null,
})

const channelOptions = [
  { id: 'email', label: 'Email' },
  { id: 'sms', label: 'Text message' },
  { id: 'push', label: 'Mobile notification' },
]

Render channelOptions with a v-for and bind each checkbox to settings.channels. Give each row a stable key such as option.id. Bind the label text for display but use the id for the checkbox value. Render frequency as radios that all share settings.frequency and use stable values such as daily and weekly. Bind consent to a single checkbox without a group value so it remains a boolean. Initialize all these values before rendering; undefined state makes it harder to distinguish a real empty choice from a missing property.

After each interaction, inspect the model rather than reading checked attributes from the DOM. Selecting email and push should produce an array containing both ids. Unchecking email should remove only email. Selecting weekly after daily should replace the scalar frequency rather than append a second value. Toggling consent should switch between true and false. These invariants are good candidates for component tests because they cover the data contract, not just whether a control is visible.

Validate and serialize selections

Validation depends on the product rule. A required channel group can require a nonempty array; a single checkbox can require true; a radio group can require a non-null choice. Report the reason near the controls and associate the message with the relevant group. A disabled submit button may be useful, but users still need a visible explanation of what must be selected. Re-check all rules in the server because browser controls can be manipulated and requests can be sent without the page.

When submitting, copy arrays if the request layer may retain or mutate the object. A shallow spread copies the form object but leaves its nested arrays shared, so copy those arrays explicitly when creating a payload snapshot. Normalize or map values at that boundary if the API expects a different representation. For example, the UI can use a string plan key while the service accepts a numeric plan id; keep that conversion in one tested function rather than encoding it in radio labels.

If options are dynamic, decide what happens when a previously selected value disappears. The form can preserve it and show that it is unavailable, remove it immediately, or block submission until the user resolves it. Silently leaving a stale id in the array can submit an option that is no longer offered. A watcher is appropriate only if changing the options has a defined state transition; otherwise reconcile explicitly when new options arrive.

Exercise and failure analysis

Change channels from an array to false and observe why the checkbox group no longer expresses multiple values. Give a radio option a duplicate value and see how two labels can produce an indistinguishable payload. Remove the initial frequency and verify that no choice is silently selected. Then add a new option whose id is numeric and make sure its type matches the existing values. Each experiment tests a specific state-shape assumption.

Test the experience with a keyboard and a screen reader as well as with a mouse. Confirm the group legend is announced, every option has a clear name, and the focus order is logical. On submission, test empty, single-selection, multi-selection, and changed-selection cases. Also test loading saved preferences: the array and scalar should select the matching controls when their options arrive. If options load asynchronously, show a loading state and prevent a misleading empty group from being mistaken for a deliberate choice.

This pattern is best when the browser's native checkbox and radio semantics match the product. A custom toggle can be appropriate for a single setting when its visual behavior has clear on/off meaning, but it must preserve keyboard, label, and checked-state semantics. For complex searchable multi-selects, use a dedicated accessible component rather than layering custom mouse handlers over ordinary checkboxes.

Checkbox and Radio Bindings: Trade-offs and Interviews

Common model mistakes

The most common defect is using the wrong state shape. A checkbox group bound to a boolean cannot represent an arbitrary set of selected values; a radio group bound to an array can accumulate values even though only one choice is valid. Start by writing the expected payload for zero, one, and multiple selections. That simple exercise often exposes whether a control should be boolean, array, nullable scalar, or a set-like structure.

Another mistake is relying on visible text as identity. A label can be translated, edited, or duplicated, so the stored value should be a stable id. Be explicit about value types. HTML values are strings unless the value is bound as an expression; mixing string ids with numeric model values can make strict equality checks fail. Normalize API data before rendering and validate the resulting payload at the boundary.

Do not confuse checked state with form submission semantics. Native controls have name and value behavior when a browser submits a form traditionally, while Vue applications often build a JSON object from reactive state. Choose one source of truth for the request. If native FormData is used, ensure names and values match the required server contract; if state is serialized, verify that the model already contains the intended values. Mixing both approaches can send duplicate or contradictory fields.

Dynamic lists and defaults

For a dynamic list, stable keys help Vue preserve the identity of each rendered input as items are inserted or reordered. A key based on the array index can make the browser preserve focus or checked appearance on the wrong row after a reorder. Use the option's stable identifier, and keep the model updated when an option is removed. Decide whether deleted selections should be removed from state or retained as historical values; the right answer depends on whether a saved preference may refer to an unavailable item.

Defaults should reflect a deliberate product choice. Preselecting a radio can speed up a common flow, but it can also cause a consequential choice to be made without the user noticing. A null initial value is appropriate when the person must actively choose. Consent and opt-in controls should be initialized according to policy and law, not merely for conversion convenience. When loading an existing record, apply the saved value after options are available and handle unknown legacy values explicitly.

Testing and accessibility

Component tests should interact with the visible labels and assert the resulting model or emitted payload. Cover checking and unchecking a single box, selecting several group members, switching between radio values, and initializing from a saved record. Include a missing or stale option. Assertions should confirm exact data types as well as values: the string "7" is not interchangeable with the number 7 in every API or validation rule.

Accessibility is part of correctness. Associate labels with controls, use fieldset and legend for related groups, provide a visible focus indicator, and make errors understandable without color. Native inputs provide useful keyboard behavior that custom controls must reproduce intentionally. If a checkbox is styled as a switch, preserve its checked state and accessible name; a visual switch does not change the model contract.

Choosing the native control

Use a checkbox for an independent yes/no decision or for each member of a multi-select set. Use radios when exactly one option should be selected from a short, visible list. A select can be more compact for many mutually exclusive options, but it hides choices until opened and has different interaction characteristics. Searchable lists, hierarchical selection, or hundreds of options usually need a purpose-built component with clear keyboard and assistive-technology support.

In an interview, describe the state shape before discussing syntax: boolean for one toggle, array for a group of independent selections, scalar for one radio choice. Then explain stable values, initialization, and validation. Mention how you test removal and keyboard access. That answer connects Vue's directive behavior to the data and interaction contract that actually matters.

Quiz

1. Which statement about Checkbox and Radio Bindings is accurate?

Question 1 options

2. When reviewing Checkbox and Radio Bindings, which point must hold?

Question 2 options

3. What model shape is appropriate for a checkbox group with several independent choices?

Question 3 options

4. How should a radio group usually share state?

Question 4 options

Flashcards

Question

What is Checkbox and Radio Bindings?

Answer

Bind grouped checkboxes to arrays and radios to a single value.

Question

Checkbox and Radio Bindings: why it matters

Answer

A checkbox bound to an array collects the value attributes of all checked boxes.

Question

Checkbox and Radio Bindings: key detail

Answer

A lone checkbox with no value attribute binds a boolean true or false.

Question

Checkbox and Radio Bindings: practical note

Answer

Radio groups share one bound value, and checking a radio assigns its own value to it.

Question

What model represents a checkbox group?

Answer

An array containing the selected values.

Revision Notes

Key Takeaways

  • 1. A checkbox bound to an array collects the value attributes of all checked boxes.
  • 2. A lone checkbox with no value attribute binds a boolean true or false.
  • 3. Radio groups share one bound value, and checking a radio assigns its own value to it.

Interview Tips

  • • Explain Checkbox and Radio Bindings with one concrete example from real vue work, not a textbook restatement.
  • • Discuss the trade-off: when Checkbox and Radio Bindings helps and when a lighter approach wins.
  • • Place Checkbox and Radio Bindings inside the Forms and Validation phase — interviewers check that you see the progression, not isolated facts.

Cheat Sheet

Checkbox and Radio Bindings Cheat Sheet

Phase: Forms and Validation | Level: beginner

Key points:

  • A checkbox bound to an array collects the value attributes of all checked boxes.
  • A lone checkbox with no value attribute binds a boolean true or false.
  • Radio groups share one bound value, and checking a radio assigns its own value to it.
  • Dynamic true-value and false-value attributes customize what a checkbox contributes.

Tags: vue, forms, binding

Continue Learning

Before You Start

  • No prerequisites listed.

Related Reading