如何创建一个将用户输入发送到另一个组件的vue模态



我正在尝试创建一个接收用户输入的模态组件,保存该信息后,它将显示在另一个组件中。例如,提示用户在模态组件(modal.vue(中分别输入他们的名字和姓氏。一旦用户保存了数据(模态上的提交方法(,数据就会显示在另一个组件(InputItem.vue(上。

目前,我有一个CreateEvent.vue组件,它包含输入元素,一个modal.vue组件是模态,一个EventItem.vue组件将在执行CreateEvent后显示输入的内容,一个EventsList.vue组件显示用户创建的所有事件,最后是app.vue,它包含模态和事件组件。

我已经能够在没有模态组件的情况下成功地使CRUD功能工作,但一旦我添加了模态,我就会感到困惑。

如果你能帮助我朝着正确的方向前进,我将不胜感激!

Modal.vue

<template>
<transition name="modal-fade">
<div class="modal-backdrop">
<div
class="modal"
role="dialog"
aria-labelledby="modalTitle"
aria-describedby="modalDescription"
>
<header class="modal-header" id="modalTitle">
<slot name="header">
Create an Event
<button
type="button"
class="btn-close"
@click="close"
aria-label="Close modal"
>
x
</button>
</slot>
</header>
<section class="modal-body" id="modalDescription">
<slot name="body">
<div @keyup.enter="addTodo">
<input
type="text"
class="todo-input"
placeholder="What needs to be done"
v-model="newTodo"
/>
<input
type="text"
placeholder="add an emoji?"
v-model="newEmoji"
/>
</div>
<button @click="doneEdit">Create Event</button>
<button @click="cancelEdit">Cancel</button>
</slot>
</section>
<footer class="modal-footer">
<slot name="footer">
I'm the default footer!
<button
type="button"
class="btn-green"
@click="close"
aria-label="Close modal"
>
Close me!
</button>
</slot>
</footer>
</div>
</div>
</transition>
</template>
<script>
export default {
name: 'modal',
data() {
return {
newTodo: '',
newEmoji: '',
idForTodo: this.todos.length + 1
}
},
methods: {
close() {
this.$emit('close')
},
addTodo() {
if (this.newTodo.trim().length == 0) return
this.todos.push({
id: this.idForTodo,
title: this.newTodo,
emoji: this.newEmoji
})
this.newTodo = ''
this.newEmoji = ''
this.idForTodo++
}
}
}
</script>

创建事件.vue

<template>
<div @keyup.enter="addTodo">
<input
type="text"
class="todo-input"
placeholder="What needs to be done"
v-model="newTodo"
/>
<input type="text" placeholder="add an emoji?" v-model="newEmoji" />
</div>
</template>
<script>
export default {
props: {
todos: {
type: Array
}
},
data() {
return {
newTodo: '',
newEmoji: '',
idForTodo: this.todos.length + 1
}
},
methods: {
addTodo() {
if (this.newTodo.trim().length == 0) return
this.todos.push({
id: this.idForTodo,
title: this.newTodo,
emoji: this.newEmoji
})
this.newTodo = ''
this.newEmoji = ''
this.idForTodo++
}
}
}
</script>

事件项.vue

<template>
<div class="todo-item">
<h3 class="todo-item--left">
<!-- <span v-if="!editing" @click="editTodo" class="todo-item--label">
{{ title }}
{{ emoji }}
</span> -->
<input
class="todo-item--edit"
type="text"
v-model="title"
@click="editTitle"
@blur="doneEdit"
/>
<input
class="todo-item--edit"
type="text"
v-model="emoji"
@click="editEmoji"
@blur="doneEdit"
/>
<!-- <button @click="doneEdit">Update</button>
<button @click="cancelEdit">Cancel</button> -->
</h3>
<button class="remove-item" @click="removeTodo(todo.id)">✘</button>
</div>
</template>
<script>
export default {
name: 'todo-item',
props: {
todo: {
type: Object,
required: true
}
},
data() {
return {
id: this.todo.id,
title: this.todo.title,
emoji: this.todo.emoji,
editing: this.todo.editing,
beforeEditCacheTitle: this.todo.title,
beforeEditCacheEmoji: this.todo.emoji
}
},
methods: {
editTitle() {
this.beforeEditCacheTitle = this.title
this.editing = true
},
editEmoji() {
this.beforeEditCacheEmoji = this.emoji
this.editing = true
},
doneEdit() {
if (this.title.trim() == '') {
this.title = this.beforeEditCacheTitle
}
if (this.emoji.trim() == '') {
this.emoji = this.beforeEditCacheEmoji
}
this.editing = false
this.$emit('finishedEdit', {
id: this.id,
title: this.title,
emoji: this.emoji,
editing: this.editing
})
},
cancelEdit() {
this.title = this.beforeEditCacheTitle
this.emoji = this.beforeEditCacheEmoji
this.editing = false
},
removeTodo(id) {
this.$emit('removedTodo', id)
}
}
}
</script>

Events.vue

<template>
<div>
<transition-group
name="fade"
enter-active-class="animated fadeInUp"
leave-active-class="animated fadeOutDown"
>
<EventItem
v-for="todo in todosFiltered"
:key="todo.id"
:todo="todo"
@removedTodo="removeTodo"
@finishedEdit="finishedEdit"
/>
</transition-group>
</div>
</template>
<script>
import EventItem from '@/components/EventItem'
export default {
components: {
EventItem
},
data() {
return {
filter: 'all',
todos: [
{
id: 1,
title: 'Eat sushi',
emoji: '💵',
editing: false
},
{
id: 2,
title: 'Take over world',
emoji: '👨🏽‍💻',
editing: false
}
]
}
},
computed: {
todosFiltered() {
if (this.filter == 'all') {
return this.todos
}
}
},
methods: {
removeTodo(id) {
const index = this.todos.findIndex(item => item.id == id)
this.todos.splice(index, 1)
},
finishedEdit(data) {
const index = this.todos.findIndex(item => item.id == data.id)
this.todos.splice(index, 1, data)
}
}
}
</script>

app.vue

<template>
<div id="app" class="container">
<button type="button" class="btn" @click="showModal">
Create Event
</button>
<Modal v-show="isModalVisible" @close="closeModal" />
<Events />
</div>
</template>
<script>
import Events from './components/Events'
import Modal from './components/Modal'
export default {
name: 'App',
components: {
Events,
Modal
},
data() {
return {
isModalVisible: false
}
},
methods: {
showModal() {
this.isModalVisible = true
},
closeModal() {
this.isModalVisible = false
}
}
}
</script>

模态组件应该发出值,而不是将其推送到todos数组中。当它发出它时,父组件(App.vue(会侦听发出的项。

我会做一些类似的事情

Modal.vue

<template>
...
// header
<section class="modal-body" id="modalDescription">
<slot name="body">
<div @keyup.enter="addTodo">
...
</div>
<button @click="handleModalSubmit">Create Event</button>
...
//footer
...
</template>
<script>
export default {
...
data() {
...
},
methods: {
...,
handleModalSubmit() {
this.$emit('todos-have-been-submitted', this.todos);
},
addTodo() {
...
this.todos.push({
id: this.idForTodo,
title: this.newTodo,
emoji: this.newEmoji
})
...
}
}
}
</script>

应用.vue

<template>
...
<Modal
@todos-have-been-submitted="handleTodoSubmission" //watch the 'todos-have-been-submitted" emission and trigger handleTodoSubmission method when the emission is detected
/>
<Events 
:todos="todos" // pass todos as a prop to the Events component
/>
...
</template>
<script>
import Events from './components/Events'
import Modal from './components/Modal'
export default {
name: 'App',
components: {
Events,
Modal
},
data() {
return {
...,
todos: []
}
},
methods: {
...,
handleTodoSubmission(todos) {
this.todos = [...todos];
}
}
}
</script>

相关内容

  • 没有找到相关文章

最新更新