You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何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>

解答

问题集中在这几个核心点:

  1. 计算属性的赋值时机错误
    data初始化时只会执行一次,此时this.numberOfRooms获取的是计算属性的初始值(大概率是undefined,因为组件初始化阶段hotels可能还未传入)。后续计算属性更新时,facilities里的function值不会同步更新,因为data中的值不是响应式依赖。

  2. 模板引用方式错误
    计算属性是属性而非函数,你在模板中直接写{{ item.function }},本质是引用了初始化时的静态值,而非实时响应的计算属性结果。

  3. 缺少空值安全判断
    当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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 10:57:04