Reputation: 95
I have a slot containing radio buttons in a parent Vue3 component, I'm passing a v-model attribute to these radio buttons and the data model exists in the parent component. However when I change the selected radio button in the slot, the data in the parent component doesn't change.
parent template:
<template>
<div class="card">
<div class="card-body">
<slot
:type="type"
/>
</div>
</div>
</template>
parent vue:
<script>
export default {
data() {
return {
type: 'standard',
}
},
}
</script>
slot content:
<parent v-slot="slotProps">
<div class="row">
<label>
<span class="required">Type</span>
</label>
<label>
Standard Model
<input v-model="slotProps.type" type="radio" name="type" value="standard" required/>
</label>
<label>
Touch Model
<input v-model="slotProps.type" type="radio" name="type" value="touch" required/>
</label>
<label>
Display Model
<input v-model="slotProps.type" type="radio" name="type" value="display" required/>
</label>
</div>
</parent>
Upvotes: 0
Views: 1470
Reputation: 501
I do not think this is a good idea and this is also not recommended by the Vue team.
Anyway, if you really need to do it, as stated by posva from the Vue team, you can pass a method instead to change the value or you can pass an object and modify a property (keep in mind this is not recommended).
Here is the object way to do it:
Parent:
<template>
<div class="card">
<div class="card-body">
<slot :myObject="myObject" />
</div>
</div>
</template>
<script>
export default {
data() {
return {
myObject: {
type: "standard",
},
};
},
};
</script>
Slot content:
<parent v-slot="slotProps">
<div class="row">
<label>
<span class="required">Type</span>
</label>
<label>
Standard Model
<input
v-model="slotProps.myObject.type"
type="radio"
name="type"
value="standard"
required
/>
</label>
<label>
Touch Model
<input
v-model="slotProps.myObject.type"
type="radio"
name="type"
value="touch"
required
/>
</label>
<label>
Display Model
<input
v-model="slotProps.myObject.type"
type="radio"
name="type"
value="display"
required
/>
</label>
</div>
</parent>
Here is the method way to do it:
Parent:
<template>
<div>
<div>
<slot :type="type" :onTypeChange="onTypeChange" />
</div>
</div>
</template>
<script>
export default {
data() {
return {
type: "touch",
};
},
methods: {
onTypeChange(event) {
this.type = event.target.value;
},
},
};
</script>
Slot content:
<parent v-slot="slotProps">
<div class="row">
<label>
<span class="required">Type</span>
</label>
<label>
Standard Model
<input
v-model="slotProps.type"
type="radio"
name="type"
value="standard"
required
@change="slotProps.onTypeChange"
/>
</label>
<label>
Touch Model
<input
v-model="slotProps.type"
type="radio"
name="type"
value="touch"
required
@change="slotProps.onTypeChange"
/>
</label>
<label>
Display Model
<input
v-model="slotProps.type"
type="radio"
name="type"
value="display"
required
@change="slotProps.onTypeChange"
/>
</label>
</div>
</parent>
Upvotes: 2