Dynamic Checkbox Binding with Vue and TypeScript
This challenge focuses on creating a reusable Vue component that dynamically renders a list of checkboxes and binds their values to a data property. This is a common requirement in forms and settings panels, allowing users to select multiple options from a predefined list. Successfully completing this challenge will demonstrate your understanding of Vue's reactivity system, component creation, and TypeScript's type safety.
Problem Description
You need to build a Vue component called CheckboxList that accepts an array of checkbox options as a prop. Each option should have a label (string) and a value (any). The component should render a checkbox for each option, and the checked state of each checkbox should be bound to an internal array of selected values. The component should also emit an event called update:model-value whenever the selected values change, allowing the parent component to track the user's selections. The model-value prop should be used to initialize the selected values.
Key Requirements:
- Dynamic Rendering: The component must dynamically render checkboxes based on the provided
optionsprop. - Two-Way Binding: The checked state of each checkbox should be synchronized with the
model-valueprop and the emittedupdate:model-valueevent. - TypeScript: The component must be written in TypeScript, ensuring type safety for the options and selected values.
- Reusability: The component should be designed to be reusable with different sets of options and data types for the
valueproperty. - Event Emission: The component must emit an
update:model-valueevent with the updated array of selected values.
Expected Behavior:
- When the component is initialized, it should render checkboxes based on the
optionsprop. - The initial checked state of each checkbox should reflect the values present in the
model-valueprop. - When a checkbox is checked or unchecked, the component should update its internal state and emit an
update:model-valueevent with the new array of selected values. - The parent component should receive the
update:model-valueevent and update its own data accordingly.
Edge Cases to Consider:
optionsprop is empty or null. The component should render no checkboxes.model-valueprop is empty or null. The component should render all checkboxes as unchecked.valueproperty of an option is null or undefined. Handle this gracefully (e.g., by skipping the option or displaying a default value).- The
valueproperty of an option is not of the same type as the values inmodel-value. TypeScript should catch this, but consider how the component behaves in such a scenario.
Examples
Example 1:
Input:
options = [{ label: 'Option 1', value: 1 }, { label: 'Option 2', value: 2 }, { label: 'Option 3', value: 3 }]
model-value = [1, 3]
Output:
Three checkboxes: "Option 1" (checked), "Option 2" (unchecked), "Option 3" (checked)
Explanation: The component renders three checkboxes, with the first and third checkboxes initially checked because their values (1 and 3) are present in the `model-value` array.
Example 2:
Input:
options = [{ label: 'A', value: 'a' }, { label: 'B', value: 'b' }, { label: 'C', value: 'c' }]
model-value = []
Output:
Three checkboxes: "A" (unchecked), "B" (unchecked), "C" (unchecked)
Explanation: The component renders three checkboxes, all initially unchecked because the `model-value` array is empty.
Example 3: (Edge Case)
Input:
options = []
model-value = [1, 2]
Output:
No checkboxes are rendered.
Explanation: The component handles the case where the `options` array is empty by rendering no checkboxes. The `model-value` is ignored in this scenario.
Constraints
- The component must be written in TypeScript.
- The component must use Vue 3.
- The component must emit the
update:model-valueevent. - The
valueproperty of each option can be of any type. - The component should be reasonably performant for lists with up to 100 options.
Notes
- Consider using
v-modelfor the checkbox input to simplify the binding logic. - Think about how to handle the case where the
valueproperty of an option is not present in themodel-valuearray. - Pay close attention to the type definitions for the
optionsandmodel-valueprops. Proper typing is crucial for TypeScript's benefits. - The
update:model-valueevent should emit the entire array of selected values, not just the changed value.