如何避免Google Places API数据缺失字段引发的Vue TypeError
问题分析与解决方案
你猜的完全没错!这个TypeError确实是来自v-for那一段代码的判断遗漏——虽然你给v-for的<p>标签加了v-if判断,但Vue的模板渲染规则里,v-for的优先级比v-if高,也就是说Vue会先尝试执行v-for的遍历逻辑,再去检查v-if的条件。这就导致当sight.opening_hours不存在时,代码会直接去读取undefined.weekday_text,自然就抛出了“Cannot read property 'weekday_text' of undefined”的错误。
解决方法有这几种,你可以根据自己的情况选择:
1. 把判断移到v-for的父元素上(最稳妥的传统写法)
用<template>标签包裹v-for的元素,把判断条件放在<template>上,这样Vue会先判断条件是否满足,再执行遍历:
<!-- 处理营业状态的代码保持不变 --> <p v-if='sight.opening_hours && sight.opening_hours.open_now'>Open now</p> <p v-if='sight.opening_hours && !sight.opening_hours.open_now'>Closed now</p> <!-- 修改后的营业时间列表渲染 --> <template v-if='sight.opening_hours && sight.opening_hours.weekday_text'> <p v-for='day in sight.opening_hours.weekday_text'>{{ day }}</p> </template>
另外注意:模板里不需要用this.sight,直接写sight就可以访问当前数据项了。
2. 使用可选链操作符简化判断(ES2020+支持)
如果你的项目支持ES2020及以上语法,可以用可选链?.来避免多层嵌套的判断,同时配合空值合并运算符??确保遍历的是一个数组:
<p v-if='sight.opening_hours?.open_now'>Open now</p> <p v-if='sight.opening_hours && !sight.opening_hours.open_now'>Closed now</p> <!-- 用可选链确保不会读取undefined的属性,空值合并保证遍历空数组而非undefined --> <p v-for='day in sight.opening_hours?.weekday_text ?? []'>{{ day }}</p>
这样即使opening_hours或weekday_text不存在,代码也会遍历一个空数组,不会抛出错误。
3. 提前在数据层面处理(从根源避免模板判断)
你也可以在获取Google Places API返回的数据后,统一处理每个景点的字段,给没有opening_hours的景点设置默认值:
// 假设这是你处理API返回数据的逻辑 const processedSights = rawSights.map(sight => { return { ...sight, opening_hours: sight.opening_hours || { weekday_text: [], open_now: false } } })
这样模板里就可以直接写v-for,不用再加额外的判断了,代码会更简洁。
内容的提问来源于stack exchange,提问作者Onyx
相关产品推荐
相关产品推荐

