【发布时间】:2020-02-10 09:57:21
【问题描述】:
这几天我都在头疼,想弄清楚如何从子组件中获取数据。
情况是这样的。
我有一个名为Post 的父组件,用户可以在其中选择日期、标题、描述,并且可以包含Event 组件的多个实例。
Event 组件包含标题、描述、与会者等字段。
用户应该能够添加多个Eventcomponents,这意味着我在Post 组件中有多个Event 组件。
所以,我不知道如何组合我的组件以在我的 Post 组件中包含一个 Event 对象数组,我以后可以将其发送到我的 API。
我需要的post对象的结构是:
// Post.vue
{
"date": '',
"name": '',
"description": '',
"events": {
{
"title": '',
"description": '',
"attendees": ''
},
{
"title": '',
"description": '',
"attendees": ''
}
}
}
所以,我不知道应该以及如何使用 vuex。我尝试使用 $emit 来传递数据,但找不到适合将数据放入 Post 模型的方法。
谁能指出我应该在哪里寻找它?
EDIT #1:添加示例代码
组件代码:
<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>
还有子组件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>
【问题讨论】:
-
子元素每次有新数据时可以
$emit。父母可以根据需要收集该数据和post到后端。没有代码示例,这就是我所能做到的最具体的了。 -
嗨大卫,我已经用示例代码更新了这个问题。我想知道的是:是否可以让
UserEvents与父组件保持同步,或者我只能使用this.$emit事件来更新父组件? -
父组件 Post 应该是唯一负责持有状态的组件。孩子们应该使用 v-model 将用户输入传输到 Post。看看:vuejs.org/v2/guide/components.html#Using-v-model-on-Components(您应该将 Event 组件视为自定义输入)
-
我也是这么想的。我只是对如何确保从
Post商店更新或删除正确的事件感到困惑。