fix(food-encyclopedia): 修复点击食物卡片 item 为 undefined 的根因
根因:小程序编译时 @click="goToFoodDetail(item)" 通过 dataset 传递 复杂对象,scroll-view 内 DOM 回收或列表异步刷新后 dataset 序列化 丢失,导致 item 变为 undefined。 修复: 1. 模板改为 @click="handleFoodItemClick(index)" 传递基本类型 2. 新增 handleFoodItemClick 方法,从 filteredFoodList 实时取 item 3. foodRowKey 始终拼接 index 避免重复 id 导致 Vue DOM 复用错乱 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -100,7 +100,7 @@
|
||||
class="food-item"
|
||||
v-for="(item, index) in filteredFoodList"
|
||||
:key="foodRowKey(item, index)"
|
||||
@click="goToFoodDetail(item)"
|
||||
@click="handleFoodItemClick(index)"
|
||||
>
|
||||
<view class="food-image-wrapper">
|
||||
<!-- 配图:优先 item.imageUrl/img/image(normalize 已对齐),再经 displayFoodImage 拼域名与占位(BUG-003) -->
|
||||
@@ -272,11 +272,11 @@ export default {
|
||||
this.loadFoodList();
|
||||
},
|
||||
methods: {
|
||||
/** 列表 :key:无效 id 曾为 '' 时多行共用同一 key,导致点击与展示错乱 */
|
||||
/** 列表 :key:始终拼接 index 保证唯一,避免重复 id 导致 Vue DOM 复用错乱、点击传参丢失 */
|
||||
foodRowKey(item, index) {
|
||||
const id = item && item.id
|
||||
const idStr = id !== undefined && id !== null && id !== '' ? String(id).trim() : ''
|
||||
if (idStr !== '' && /^-?\d+$/.test(idStr)) return 'id-' + idStr
|
||||
if (idStr !== '' && /^-?\d+$/.test(idStr)) return 'id-' + idStr + '-' + index
|
||||
const n = item && item.name != null ? String(item.name).trim() : ''
|
||||
return 'idx-' + index + '-' + (n || 'row')
|
||||
},
|
||||
@@ -1009,8 +1009,22 @@ export default {
|
||||
}
|
||||
}, 300);
|
||||
},
|
||||
/**
|
||||
* 点击食物卡片的入口方法:通过 index 从 filteredFoodList 实时获取 item。
|
||||
* 小程序编译时 @click="fn(item)" 会通过 dataset 传递复杂对象,scroll-view 内
|
||||
* DOM 回收或列表异步刷新后 dataset 可能丢失导致 item 为 undefined。
|
||||
* 改为传递基本类型 index,在方法内从响应式数据实时取值,彻底解决此问题。
|
||||
*/
|
||||
handleFoodItemClick(index) {
|
||||
const item = this.filteredFoodList[index]
|
||||
if (!item || typeof item !== 'object') {
|
||||
console.warn('[food-encyclopedia] handleFoodItemClick: index', index, '对应 item 为空,filteredFoodList.length =', this.filteredFoodList.length)
|
||||
return
|
||||
}
|
||||
this.goToFoodDetail(item)
|
||||
},
|
||||
goToFoodDetail(item) {
|
||||
// 防御性校验:避免 item 为空时报错(fix: TypeError Cannot read property 'id' of undefined)
|
||||
// 防御性校验(兜底,正常路径由 handleFoodItemClick 保证 item 有效)
|
||||
if (!item || typeof item !== 'object') {
|
||||
console.warn('[food-encyclopedia] goToFoodDetail: item 为空,跳过跳转', item)
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user