如何在非表单元素使用v-model?自定义组件绑定VSwitch值至父组件
Hey Marcus, great question! What you're trying to achieve is absolutely possible—let's walk through how to make your custom my-component work seamlessly with v-model so the parent component can receive the selected values from those v-switch controls.
Understanding Vue's v-model Syntax Sugar
First, it helps to remember that v-model is just Vue's syntax sugar for two core behaviors:
- Binding a component's
valueprop to a parent variable - Listening for an
inputevent emitted by the component to update that variable
To make your custom component support v-model, you just need to sync your internal state with the value prop and emit an input event whenever that state changes.
Modify Your Custom Component
Right now, your toggledData array is isolated to the child component. Let's connect it to the parent's v-model using a computed property (this is cleaner than using a watcher for this use case):
<template> <div> <v-switch v-model="toggledData" value="John"></v-switch> <v-switch v-model="toggledData" value="Andrew"></v-switch> <v-switch v-model="toggledData" value="Melissa"></v-switch> <v-switch v-model="toggledData" value="Elizabeth"></v-switch> </div> </template> <script> export default { props: ['value'], computed: { toggledData: { // Get the current value from the parent's v-model get() { // Fallback to an empty array if no initial value is provided return this.value || []; }, // When toggledData changes (via v-switch interactions), emit the new value to the parent set(newToggledValues) { this.$emit('input', newToggledValues); } } } } </script>
How This Works:
- Vuetify's
v-switchautomatically manages adding/removing values from thetoggledDataarray when switches are toggled (this built-in behavior is why it works similarly tov-treeview). - The computed property's
getmethod ensures the child starts with the parent's initial value (if any). - Every time a switch is toggled, the
setmethod fires and emits aninputevent with the updated array—this tells the parent'sv-modelto update its bound variable.
Using the Component in the Parent
Now you can use your component exactly how you wanted:
<template> <div> <my-component v-model="returnedData"></my-component> <p>Selected names: {{ returnedData.join(', ') }}</p> </div> </template> <script> import MyComponent from './MyComponent.vue'; export default { components: { MyComponent }, data() { return { returnedData: [] // This will automatically update with selected values }; } } </script>
Using v-model on Non-Form Elements
You asked about using v-model on non-form elements—this works using the exact same principle! v-model doesn't care if the component is form-related or not; it just relies on the value prop + input event pattern (or a custom pattern you define).
For example, here's a simple non-form component that uses v-model to toggle an active state:
<template> <div @click="toggleActive" :class="{ active: isActive }" style="padding: 1rem; cursor: pointer;" > {{ isActive ? 'Active' : 'Inactive' }} </div> </template> <script> export default { props: ['value'], computed: { isActive: { get() { return this.value; }, set(newState) { this.$emit('input', newState); } } }, methods: { toggleActive() { this.isActive = !this.isActive; } } } </script> <style scoped> .active { background-color: #4CAF50; color: white; } </style>
Customizing the Prop/Event Names (Optional)
If you don't want to use value and input (maybe your component already uses value for something else), you can define a custom model option in your component:
<script> export default { model: { prop: 'selectedNames', // Custom prop name event: 'update:selectedNames' // Custom event name }, props: ['selectedNames'], // Use the custom prop name here computed: { toggledData: { get() { return this.selectedNames || []; }, set(newVal) { this.$emit('update:selectedNames', newVal); } } } } </script>
The parent can still use v-model normally—Vue will automatically map it to your custom prop and event.
内容的提问来源于stack exchange,提问作者Marcus




