Vue3组件中向ref数组添加对象时被覆盖问题求助
问题解决:Vue中向ref数组push对象时原有条目被覆盖
问题根源
你遇到的问题是因为引用类型的传递特性:QuizData是父组件传递的响应式对象(引用类型),你创建的quizDict直接引用了QuizData.question。当父组件切换题目、更新QuizData的内容时,数组中之前存入的所有quizDict的qst属性都会指向同一个更新后的QuizData.question,看起来就像是旧条目被新内容覆盖了。
另外,如果你的问卷是由多个该子组件实例组成(每个题目一个组件),每个子组件的QuizToSub都是独立数组,根本无法收集所有题目的答案,这也会造成“数据没正确存储”的误解。
修复方案
方案1:切断引用,深拷贝题目内容
如果只需要在当前子组件存储答案,修改quizDict的创建逻辑,把QuizData.question的值深拷贝出来,而不是直接引用:
const scrollToNext = (response) => { const nextSection = document.getElementById(`${id + 2}`); // 用JSON序列化/反序列化实现深拷贝(适合可序列化的内容,如字符串、普通对象) const quizDict = { qst: JSON.parse(JSON.stringify(QuizData.question)), rep: response }; QuizToSub.value.push(quizDict) console.log(QuizToSub) if (nextSection) { nextSection.scrollIntoView({ behavior: 'smooth' }); } };
如果QuizData.question包含不可序列化的内容(如函数、Symbol),可以使用lodash的cloneDeep方法:
import { cloneDeep } from 'lodash'; // ... const quizDict = { qst: cloneDeep(QuizData.question), rep: response };
方案2:父组件统一管理答案数组(推荐)
如果要收集所有题目的答案,应该把QuizToSub放在父组件中,子组件通过emit事件传递答案:
父组件代码
<template> <QuizComponent v-for="(quiz, index) in quizList" :key="index" :QuizData="quiz" :id="index" @submit-answer="addAnswer" /> </template> <script setup> import { ref } from 'vue'; import QuizComponent from './QuizComponent.vue'; // 所有题目数据 const quizList = ref([/* 你的题目列表 */]); // 统一存储所有答案的数组 const QuizToSub = ref([]); // 接收子组件传递的答案并添加到数组 const addAnswer = (answer) => { QuizToSub.value.push(answer); }; </script>
子组件修改代码
<script setup> import { ref } from 'vue' const { QuizData, id } = defineProps({ QuizData: Object, id: Number }) // 定义emit事件 const emit = defineEmits(['submit-answer']); const scrollToNext = (response) => { const nextSection = document.getElementById(`${id + 2}`); // 深拷贝题目内容,避免引用问题 const quizDict = { qst: JSON.parse(JSON.stringify(QuizData.question)), rep: response }; // 向父组件传递答案 emit('submit-answer', quizDict); if (nextSection) { nextSection.scrollIntoView({ behavior: 'smooth' }); } }; </script>
内容的提问来源于stack exchange,提问作者Wlid El Bahdja
相关产品推荐
相关产品推荐

