You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3中通过Prop传值至子组件,编辑后无法保存问题求助

问题描述

希望将值传入子组件,由子组件独立执行保存操作,父组件无需相关逻辑。目前已成功传入对象,但无法保存更新后的内容。已知props是只读的,尝试复制props但仅维护了一个数据模型,不理解为何需要向父组件emit后再传回子组件,寻求解决方案。


父组件代码

<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>

解决方案

核心问题是子组件未维护独立的编辑状态,提交时用的是原始props值而非用户编辑后的内容。要实现子组件独立完成编辑保存,按以下步骤修改:

1. 子组件修改(核心调整)

<template>
    <div>
        <div>
            <!-- 用v-model绑定本地编辑变量,实时同步输入内容 -->
            <textarea id="updateTextArea" rows="10" v-model="localTodo.post"></textarea>
        </div>
    
        <div>
            <button data-modal-toggle="defaultModal" type="button" @click="saveEdit">Save</button>
        </div>
    </div>
</template>

<script lang="ts" setup>
import { api } from "../lib/api";
import { ref, watch } from "vue";

// 修正props类型:传入的是对象而非字符串
const props = defineProps({
  todo: Object,
})

const emit = defineEmits(['toggle']);

// 复制props的todo到本地响应式变量,作为编辑数据源
const localTodo = ref({...props.todo});

// 监听props变化,确保打开新的编辑内容时同步本地状态
watch(() => props.todo, (newTodo) => {
  localTodo.value = {...newTodo};
}, {deep: true})

function saveEdit() {
  try {
    // 使用本地编辑后的最新值调用API
    api.updateBlog(localTodo.value.blogId, localTodo.value.post).then(res => {
      emit('toggle', false); // 保存成功后关闭模态框
    })
  } catch (e) {
    console.log('Error while updating post: '+ e)
  }
}
</script>

2. 父组件简化(移除不必要逻辑)

<template>
    <div v-show="isOpened">
        <!-- 移除不需要的update:todo事件和updatedText props -->
        <EditModal @toggle="closeModal" :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('');

function closeModal() {
    isOpened.value = false
}
function openModal(value: string) {
    isOpened.value = true
    modalPost.value = value
}

// 若保存后需要刷新列表,可在子组件新增emit事件,父组件监听后调用posts()即可
</script>

关键说明

  • 修正props类型:之前将todo定义为String是错误的,实际传入的是对象,需改为Object。
  • 本地维护编辑状态:通过localTodo复制props数据,避免直接修改只读的props,同时保证编辑内容实时更新。
  • 去掉冗余emit:子组件独立完成保存,无需向父组件传递更新后的值,仅需emit关闭模态框的事件。

内容的提问来源于stack exchange,提问作者Mike3355

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 02:21:00