Vue动态生成表单中复选框v-model全局同步问题的解决请求
问题分析与解决方案
你遇到的问题核心是引用类型的浅拷贝导致的状态同步——所有动态添加的表单项里的players数组,其实都指向同一个this.contact对象,所以修改任意一个复选框的checked状态,都会影响所有项的同一名玩家的状态。
为什么文本输入没问题?
文本输入绑定的是字符串(基本类型),赋值的时候是值拷贝,每个表单项的date、description等都是独立的;但players是数组(引用类型),直接赋值players: this.contact只是把引用传过去,所有项共享同一个数组实例。
修复步骤
- 初始化第一个表单项时,使用数组拷贝
- 添加新表单项时,创建
contact数组的深拷贝,避免共享引用
修改后的代码示例
首先调整getContacts里的初始化逻辑:
getContacts() { this.pageLoader = true; this.$http.get('/pkpar/get-contacts') .then(({ data }) => { this.contacts = data.contacts; // 这里创建一个新数组,而不是直接赋值 const initialPlayers = this.contacts.map(item => ({ id: item.id, fullName: item.fullName, checked: true })); this.contact = initialPlayers; this.journal[0].players = [...initialPlayers]; // 浅拷贝即可,因为每个元素是普通对象 this.pageLoader = false; }) .catch(error => { console.log(error); }); }
然后修改addInput方法,每次添加新项时都创建一个独立的players数组:
addInput() { // 对contact数组进行浅拷贝,确保每个新项的players是独立的 const newPlayers = this.contact.map(player => ({...player})); this.journal.push({ date: "", timeStart: "", timeEnd: "", players: newPlayers, description: "" }); }
另外,注意你的data初始化里players: ""是字符串,应该改成players: [],避免初始类型不匹配:
data() { return { contact: [], journal: [{ date: "", timeStart: "", timeEnd: "", players: [], // 这里改成空数组 description: "" }], contacts: [], } },
额外优化建议
- 循环复选框时,给每个
v-for加上:key,比如:key="item.id",提升Vue的渲染性能:
<div class="form-check" v-for="item in input.players" :key="item.id"> <input v-model="item.checked" type="checkbox" class="form-check-input" :id="'id-'+item.id+'set'+index"> <label class="form-check-label" :for="'id-'+item.id+'set'+index">{{ item.fullName }}</label> </div>
这样修改后,每个表单项的players数组都是独立的实例,复选框的状态就只会影响当前项的玩家了。
内容的提问来源于stack exchange,提问作者michael6969
相关产品推荐
相关产品推荐

