通过prop传递一个值,编辑它并保存新值3



我试图将一个值传递给子组件。然后,子组件将执行保存操作。家长不需要知道这件事。我可以传入对象,但不能保存其更新后的形式。

父母

<template>
<div v-show="isOpened">
<EditModal @toggle="closeModal" @update:todo="submitUpdate($event)"
:updatedText="editText" :todo="modalPost" />
</div>
</template>
<script setup lang="ts">
import Post from "../components/Post.vue";
import { api } from "../lib/api";
import { ref } from "vue";
import { onMounted } from "vue-demi";
import EditModal from "../components/EditModal.vue";
const postArr = ref('');
const message = ref('');
let isOpened = ref(false);
let modalPost = ref('');
let editText = ref('');
function closeModal() {
isOpened.value = false
}
function openModal(value: string) {
isOpened.value = true
modalPost.value = value
}
// call posts so the table loads updated item
function submitUpdate(value: any) {
console.log("called update in parent  " + value)
editText.value = value
posts()
}
</script>

孩子EditModal

<template>
<div>
<div>
<textarea id="updateTextArea" rows="10" :value="props.todo.post"></textarea>
</div>

<!-- Modal footer -->
<div>
<button data-modal-toggle="defaultModal" type="button"
@click="update(props.todo.blogId, props.todo.post)">Save</button>
</div>
</div>
</template>
<script lang="ts" setup>
import { api } from "../lib/api";
import { reactive, ref } from "vue";
const props = defineProps({
todo: String,
updatedText: String,
})
const emit = defineEmits(
['toggle','update:todo']
);
function setIsOpened(value: boolean) {
emit('toggle', value);
}
function update(id: string, value: string) {
console.log('the value   ' + value)
try {
api.updateBlog(id, value).then( res => {
emit('update:todo', value)
emit('toggle', false);
})
} catch (e) {
console.log('Error while updating post: '+ e)
}
}
</script>

我知道道具是只读的,所以我试着复制它,我只能有一个模型。我不明白为什么我应该把$emit传递给父节点,并把一些东西传递给另一个变量,再传递给子节点。我试图在文本传递到一个模态组件,它可以编辑文本和子组件保存它。

建议吗?

首先,您的组件应该命名为EditTodo而不是EditModal,因为您没有编辑模态。所有Edit组件都应该将props重写为新的局部变量,如ref或reactive,这样你就可以对它们进行工作,它们将不再是只读的。

儿童EditTodo.vue

<template>
<div>
<div>
<textarea id="updateTextArea" rows="10" v-model="data.todo.title"></textarea>
</div>
<div>
<button data-modal-toggle="defaultModal" type="button" @click="update()">Save</button>
</div>
</div>
</template>
<script setup lang="ts">
import { api } from "../lib/api";
import { reactive } from "vue";
const props = defineProps<{ id: number, todo: { title: string} }>()
const emit = defineEmits(['toggle']);
const data = reactive({ ...props })
// I assuming api.updateBlog will update data in database
// so job here should be done just need toogle false modal
// Your array with todos might be not updated but here is
// no place to do that. Well i dont know how your API works.
// Database i use will automaticly update arrays i updated objects
function update() {
try {
api.updateBlog(data.id, data.todo ).then(res => {
emit('toggle', false);
})
}
}
</script>

父母

<template>
<div>
<BaseModal v-if="todo" :show="showModal">
<EditTodo :id="todo.id" :todo="todo.todo" @toggle="(value) => showModal = value"></EditTodo>
</BaseModal>
</div>
</template>
<script setup lang="ts">
const showModal = ref(false)
const todo = reactive({ id: 5, todo: { title: "Todo number 5"} })
</script>

我将一个模态对象与edit form分开,这样你就可以创建更多的表单并使用相同的模态。这里是一个简单的,不完全功能的模态.

<template>
<div class="..."><slot></slot></div>
</template>
<script setup>
defineProps(['show'])
defineEmits(['toogle'])
</script>

当用户点击modal之外的某个位置时,你可能想要关闭modal。

最新更新