I'm breaking my head for a few days now, trying to figure out how to grab the data from child components.
Situation is like this.
I have one parent component called Post where user can select date, title, description and which can contain multiple instances of Event compontents.
Event component contains fields like title, description, attendees.
User should be able to add multiple Eventcomponents which means I have multiple components Event within the Post component.
So, I can't figure out how can I compose my components to have an array of Event objects inside my Post component which I can later on send to my API.
the structure of the post object I need is:
// Post.vue
{
"date": '',
"name": '',
"description": '',
"events": {
{
"title": '',
"description": '',
"attendees": ''
},
{
"title": '',
"description": '',
"attendees": ''
}
}
}
So, I don't know should and how I would use vuex for it. I've tried using $emit to pass the data but I couldn't find it fit to get the data into Post model.
Can someone point me where should I look for it?
EDIT #1: Added sample code
The code for the components:
<template>
<v-form>
<v-container>
<v-row>
<v-col
cols="12"
md="4"
>
<v-date-picker v-model="post.date" scrollable>
<v-spacer />
<v-btn text color="primary" @click="modal = false">
Cancel
</v-btn>
<v-btn text color="primary" @click="$refs.dialog.save(date)">
OK
</v-btn>
</v-date-picker>
</v-col>
<v-col
cols="12"
md="4"
>
<v-text-field
v-model="post.name"
label="name"
required
/>
</v-col>
<v-col
cols="12"
md="4"
>
<v-textarea
v-model="post.description"
name="description"
label="Description"
dense
value
rows="4"
hint
/>
</v-col>
</v-row>
<v-row>
<v-btn primary rounded @click="addLine">
Add Event
</v-btn>
<v-expansion-panels accordion>
<UserEvent
v-for="(line, index) in lines"
:key="index"
@addLine="addLine"
@removeLine="removeLine(index)"
/>
</v-expansion-panels>
</v-row>
</v-container>
</v-form>
</template>
<script>
import UserEvent from './partials/event'
export default {
name: 'Post',
components: { UserEvent },
data () {
return {
post: [],
lines: [],
blockRemoval: true
}
},
watch: {
lines () {
this.blockRemoval = this.lines.length <= 1
}
},
mounted () {
},
methods: {
addLine () {
const checkEmptyLines = this.lines.filter(line => line.number === null)
if (checkEmptyLines.length >= 1 && this.lines.length > 0) { return }
this.lines.push({
title: null,
description: null,
attendees: null
})
},
removeLine (lineId) {
if (!this.blockRemoval) { this.lines.splice(lineId, 1) }
}
}
}
</script>
And the child component UserEvent
// UserEvent.vue
<template>
<v-expansion-panel>
<v-expansion-panel-header>Event details</v-expansion-panel-header>
<v-expansion-panel-content>
<v-row>
<v-col cols="12" md="6">
<v-text-field
v-model="event.title"
label="Title"
required
/>
</v-col>
<v-col
cols="12"
md="6"
>
<v-text-field
v-model="event.atttendees"
label="Atendees"
required
/>
</v-col>
<v-col
cols="12"
md="12"
>
<v-textarea
v-model="event.description"
name="description"
label="Description"
dense
value
rows="4"
hint
/>
</v-col>
<v-col
cols="12"
md="3"
>
<div class="block float-right">
<v-btn @click="removeLine(index)" />
<v-btn v-if="index + 1 === lines.length" @click="addLine" />
</div>
</v-col>
</v-row>
</v-expansion-panel-content>
</v-expansion-panel>
</template>
<script>
export default {
name: 'UserEvent',
props: ['line', 'index'],
data () {
return {
event: []
}
},
methods: {
addLine () {
this.$emit('addLine')
},
removeLine (index) {
this.$emit('removeLine', index)
}
}
}
</script>
$emiteach time they have new data. The parent could collect that data andpostas needed to a backend. This is about as specific as I can be without a code sample.UserEventsin sync with the parent component, or I can update the parent component only by usingthis.$emitevents?Poststore.