Vue组件添加响应式对象至数组后复选框状态异常问题排查
修复Vue假期列表复选框联动异常问题
问题根源
- v-model指令误用:原代码里
<b-form-checkbox>用了:v-model,这是错误写法——v-model是Vue内置指令,不需要加冒号(冒号是v-bind的简写,用于绑定普通属性),错误绑定会导致复选框状态无法正确关联数据。 - 列表项key重复:新增假期时固定写死
id: "vac-2",导致所有新增项的key完全相同。Vue会复用相同key的列表组件,这就是点击第二个复选框时第一个跟着变化的原因。 - 违反单向数据流:直接把props的
value赋值给data里的employee,相当于直接修改父组件传递的对象,不仅不符合Vue设计原则,还可能引发响应式异常。
修复方案
1. 修正v-model绑定
把复选框的:v-model改成v-model:
<b-form-checkbox v-model="vacation.yearlyRepetition"> Jährlich wiederholend </b-form-checkbox>
2. 生成唯一的列表项key
每次新增假期时,根据现有列表长度生成唯一id,避免重复:
addVacation() { const newId = `vac-${this.employee.vacations.length + 1}`; this.employee.vacations.push({ id: newId, date: new Date().toISOString().split('T')[0], // 用当前日期当默认值更合理 yearlyRepetition: false, }); }
3. 深拷贝props数据,保持组件状态独立
在data里深拷贝props的value,不要直接引用父组件对象:
data() { return { employee: JSON.parse(JSON.stringify(this.value)), }; },
完整修复代码
<template> <div> <b-row v-for="vacation in employee.vacations" :key="vacation.id"> <b-col> <b-input type="date" v-model="vacation.date"></b-input> </b-col> <b-col> <b-form-checkbox v-model="vacation.yearlyRepetition"> Jährlich wiederholend </b-form-checkbox> </b-col> </b-row> <b-button @click="addVacation"> <b-icon-plus /> </b-button> </div> </template> <script> export default { data() { return { employee: JSON.parse(JSON.stringify(this.value)), }; }, props: { value: { type: Object, default: () => { return { vacations: [ { id: "vac-1", date: "2022-12-23", yearlyRepetition: true, }, ], }; }, }, }, methods: { addVacation() { const newId = `vac-${this.employee.vacations.length + 1}`; this.employee.vacations.push({ id: newId, date: new Date().toISOString().split('T')[0], yearlyRepetition: false, }); }, }, }; </script>
内容的提问来源于stack exchange,提问作者Andreas Nicklaus
相关产品推荐
相关产品推荐

