使用Prop作为初始值时Inertia误删条目?技术求助
问题:将Prop作为初始值传入组件时,Inertia.js条目删除显示异常
当把Prop作为初始值传入子组件后,执行删除操作时出现异常:删除某条评论(比如第二条),页面显示底部条目被删除,目标条目(内容为777)仍存在;但刷新页面后,目标条目消失,原本显示被删的条目重新出现。仅在子组件中将initialMessage存入独立的message ref时才会触发该问题,请问原因是什么?
Laravel 控制器代码
展示问题及评论接口
public function index(): Response { $issue = Issue::with('comments')->find(52); return Inertia::render('Dashboard/Issues/Test', compact('issue')); }
删除评论接口
public function destroy(Comment $comment) { $comment->delete(); return back(); }
Vue 代码
父页面(展示评论列表)
<template> <div> <input v-model="text"> <button></button> <ul> <TestB v-for="comment in issue.comments" :id="comment.id" :initial-message="comment.message"></TestB> </ul> </div> </template> <script setup> import TestB from './../../../components/comments/TestB.vue'; import {ref} from "vue"; const prop = defineProps(['issue']); const text = ref(''); </script>
子组件TestB(存储初始值为独立ref)
<template> <li> <span>{{ message }}</span> <button class="text-red-600 p-1" @click="deleteC">DELETE</button> </li> </template> <script setup> import {Inertia} from "@inertiajs/inertia"; import {ref} from "vue"; const prop = defineProps(['id', 'initialMessage']); const message = ref(prop.initialMessage); function deleteC(id) { console.log('DELETE'); console.log(prop.id); Inertia.delete('/dashboard/issues/comments/' + prop.id); } </script>
原因分析
问题核心是Vue的v-for未设置唯一key。Vue默认会用数组索引作为v-for的key,当父组件的issue.comments数组删除元素后,数组长度减少,Vue会复用已有的组件实例:
- 比如删除索引1的元素,原索引2的元素会移到索引1的位置,Vue会复用原来索引1的组件实例,而该组件的
message仅在初始化时赋值一次,不会随新传入的initialMessage更新,导致页面显示原索引1的内容(即777仍存在),最后一个组件被销毁,看起来像是删除了最后一条。 - 刷新页面后,所有组件重新初始化,数据从后端重新获取,显示恢复正常。
解决方案
给v-for添加唯一key,使用评论的id作为标识:
<TestB v-for="comment in issue.comments" :key="comment.id" <!-- 新增唯一key --> :id="comment.id" :initial-message="comment.message" ></TestB>
这样Vue能准确识别每个组件对应的评论,删除时会正确销毁对应id的组件实例,页面显示将与实际数据一致。
内容的提问来源于stack exchange,提问作者Adam
相关产品推荐
相关产品推荐

