为何Vue中方法可展示数据,改用计算属性后却无法显示?
问题
我有一个名为hotels的数组类型prop,该数组包含嵌套的酒店数组,每个酒店对象包含房间数等各类属性。为展示这些属性,我定义了一个facilities数组,其中每个元素存储图标类名、名称和一个函数,通过方法调用该函数后,在模板中使用v-for循环遍历展示。
我希望该数组具备响应式特性,因此尝试将方法改为计算属性,但此时数据不再显示。请问我忽略了什么?
模板代码
<ul class="mb-2"> <li class="list-group-item mb-1"> </li> <template v-for="(item, index) in facilities"> <li :key="index" v-if="item.function != null"> <i :class="item.iconClass"></i> {{ item.name }} <strong class="ml-2"> {{ item.function }} </strong> </li> </template> </ul>
脚本代码
<script> export default { props: { hotels: Array, }, data() { return { facilities: [ { iconClass: "fas fa-door-open fa-fw fa-lg icon-class ml-2 mr-2", name: 'Number of rooms:', function: this.numberOfRooms, } ], } }, computed: { numberOfRooms(){ if(this.hotels[0].hotel.numberRooms > 0) { return this.hotels[0].hotel.numberRooms } }, } } </script>
解答
问题集中在这几个核心点:
计算属性的赋值时机错误
data初始化时只会执行一次,此时this.numberOfRooms获取的是计算属性的初始值(大概率是undefined,因为组件初始化阶段hotels可能还未传入)。后续计算属性更新时,facilities里的function值不会同步更新,因为data中的值不是响应式依赖。模板引用方式错误
计算属性是属性而非函数,你在模板中直接写{{ item.function }},本质是引用了初始化时的静态值,而非实时响应的计算属性结果。缺少空值安全判断
当hotels未传入、结构异常或numberRooms不大于0时,numberOfRooms没有返回值,会默认返回undefined,导致显示异常。
修复方案
把facilities改为计算属性,让它直接依赖hotels和numberOfRooms,实现响应式同步:
<script> export default { props: { hotels: Array, }, computed: { numberOfRooms(){ // 空值安全判断,避免报错 if (!this.hotels?.[0]?.hotel?.numberRooms) { return 0; // 可根据需求改为空字符串或其他默认值 } return this.hotels[0].hotel.numberRooms; }, facilities() { return [ { iconClass: "fas fa-door-open fa-fw fa-lg icon-class ml-2 mr-2", name: 'Number of rooms:', value: this.numberOfRooms, // 直接引用计算属性的实时值 } ]; } } } </script>
同时修改模板,将item.function改为item.value:
<ul class="mb-2"> <li class="list-group-item mb-1"> </li> <template v-for="(item, index) in facilities"> <li :key="index" v-if="item.value != null"> <i :class="item.iconClass"></i> {{ item.name }} <strong class="ml-2"> {{ item.value }} </strong> </li> </template> </ul>
核心逻辑说明
facilities转为计算属性后,会自动跟踪numberOfRooms和hotels的变化,依赖更新时自动重新计算,保证响应式。- 使用可选链操作符
?.避免hotels结构异常导致的报错,提升代码健壮性。 - 直接在
facilities中引用计算属性,而非提前赋值到data,确保值始终同步。
内容的提问来源于stack exchange,提问作者Maflec
相关产品推荐
相关产品推荐

