子组件数据刷新问题
问题描述: 父组件在
v-for中使用子组件,子组件有两个业务功能,分别是发起报检和取消报检;业务需求是调用上述两个功能后,子组件的数据能够重新刷新。分别在子组件的两个业务方法中通过this.$emit('refresh')调用了父组件的数据刷新方法,但是子组件的数据并没有正确的重新刷新
问题分析
v-for 遍历的是 tables 数组变量,数据未成功刷新的原因可能是 tables 数组的引用没有改变,导致 Vue 无法检测到数据变化
解决方案
- 修改父组件的 refresh 方法,确保每次都会创建一个新的数组引用:接口返回数据后,使用展开运算符创建新数组,确保引用改变
- 在子组件中,添加
watch监听props中的数据变化,并调用子组件中的数据初始化方法: - 在父组件中,修改模板以添加
key属性,强制 Vue 重新创建组件:<inspection-table @cell-edit="handleCellEdit" @refresh="initData" v-for="(item, index) in tables" :key="'table-' + index + '-' + (item.updateKey || 0)" // 添加updateKey :ref="`InspectionTable${index}`" :initComponentData="item" :disabled="false" :parameter-value="parameterValue" :indexItem="index" ></inspection-table> - 父组件初始化数据时,为每个表格项添加时间戳作为更新标识:
initData() { const data = { expId: this.parameterValue.expId, projectId: this.parameterValue.projectId }; InspectionShowList(data).then(res => { if (res.code === 200) { const resultData = res.result || []; // 添加时间戳作为更新标识 const timestamp = new Date().getTime(); this.tables = resultData.length > 0 ? resultData.map(item => ({...item, updateKey: timestamp})) : [{ updateKey: timestamp }]; this.allComponentData = resultData.length > 0 ? resultData.map(item => item.data) : []; } }).catch(error => { this.$message.error('获取数据失败:' + error.message); }); }
总结
- 强制组件重新渲染:通过修改
v-for的key属性,确保每次数据更新时 Vue 都会重新创建组件实例。 - 深度监听数据变化:使用
watch监听 父组件传递的props中initComponentData的深度变化,确保数据更新时能正确响应。 - 保持数据响应式:使用展开运算符
...创建新数组,确保 Vue 能检测到数据变化。 - 添加更新标识:使用时间戳作为
updateKey,确保每次数据更新时Key都会改变。 - 清理旧数据,在重新初始化数据前,先清空现有数据,避免数据残留。