Vue.js子组件渲染异常:仅热更新显示刷新后消失求助
Vue子组件渲染异常:页面刷新数据消失,热更新才显示
问题现象
- 页面刷新后表格无数据,仅在VSCode修改代码触发热更新时,表格数据正常显示
- 控制台无报错,Vue DevTools中
distinctWeekYear、dataTable等待渲染数据状态正常 - 父组件在
mounted钩子中完成数据获取、处理后,通过props传递给子组件
核心原因
Vue 2的响应式系统默认无法追踪对象新增属性的变化。父组件中dataTable初始定义为空对象,在createDataForTable方法中通过this.dataTable[e] = {...}直接添加索引属性时,这些新增属性不会被纳入响应式追踪,因此数据更新无法触发子组件重新渲染。
而热更新时Vue会重新初始化组件,此时已添加的属性会被自动转为响应式,所以能正常显示数据。
解决方案
1. 将dataTable改为数组存储(推荐)
dataTable是按索引顺序排列的行数据,用数组更符合场景,且数组的变更操作(如索引赋值、push)能被Vue自动追踪:
// 父组件data中修改初始化定义 data() { return { // ... dataTable: [], // 从空对象改为空数组 // ... } }
2. 用$set确保对象属性的响应式(若必须用对象)
如果坚持用对象存储dataTable,需通过this.$set添加属性,强制纳入响应式系统:
// 在createDataForTable的循环中修改赋值逻辑 this.$set(this.dataTable, e, { reach: 0, impressions: 0, spend: 0 })
3. 生成新对象/数组后整体赋值
避免直接修改原有对象,而是生成全新的dataTable后整体赋值,强制触发响应式更新:
createDataForTable() { const data = this.$store.state.dataFaceAds.data; const weekNumbers = data.map(item => item.week_number); this.distinctWeekYear = [...new Set(weekNumbers)]; // 生成全新的dataTable数组 const newDataTable = []; for (let e = 0; e < this.distinctWeekYear.length; e++){ newDataTable[e] = { reach: 0, impressions: 0, spend: 0 }; const shouldAddDataType = Object.values(this.filtersType).every(value => value); const shouldAddDataClass = Object.values(this.filtersClass).every(value => value); data.filter(element => element.week_number === this.distinctWeekYear[e]) .forEach(element => { if ((shouldAddDataType || this.filtersType[element.type]) && (shouldAddDataClass || this.filtersClass[element.class])) { newDataTable[e].reach += element.reach; newDataTable[e].impressions += element.impressions; newDataTable[e].spend += element.spend; } }); } // 整体赋值触发响应式更新 this.dataTable = newDataTable; }
4. 修正子组件props类型定义
子组件中rowData按数组方式遍历(v-for="(row, rowIndex) in rowData"),但props类型定义为Object | Array,建议统一为Array避免类型混淆:
// 子组件props修改 props: { // ... rowData: { type: Array, required: true, }, // ... }
内容的提问来源于stack exchange,提问作者João Denari
相关产品推荐
相关产品推荐

