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

async函数在Vue模板中返回[object Promise]而非布尔值的问题

问题原因

async 函数的返回值本质是一个 Promise对象,而JavaScript里任何对象都会被视为“真值”,所以你在模板的v-if里直接调用isAssigned时,不管Promise最终resolve的是true还是false,v-if都会判定为true,导致一直显示"Assigned"。

解决方案

不能在模板里直接用async函数做条件判断,正确的做法是提前获取所有issue的分配状态,存到组件数据中,模板直接使用这些预存的状态值。

方法1:预加载所有issue的分配状态

在组件初始化时,先获取details数据,再批量请求每个issue的分配状态,把结果存在一个以issueId为键的对象里,模板直接通过这个对象取值判断。

Vue3 示例代码

import { ref, onMounted } from 'vue';
import axios from 'axios';

export default {
  setup() {
    const details = ref([]);
    // 存储每个issue的分配状态,键为issueId,值为布尔值
    const assignedStatus = ref({});

    // 获取详情列表数据
    const fetchDetails = async () => {
      // 这里替换成你获取details的实际逻辑
      // details.value = await axios.get(...)
    };

    // 批量获取所有issue的分配状态
    const fetchAssignedStatuses = async () => {
      // 生成所有请求Promise
      const statusPromises = details.value.map(item => 
        axios.get(route('issueAssigned', { issueId: item.issues.id }))
          .then(res => {
            assignedStatus.value[item.issues.id] = res.data.isAssigned;
          })
          .catch(err => {
            console.error(err);
            assignedStatus.value[item.issues.id] = false;
          })
      );
      // 等待所有请求完成
      await Promise.all(statusPromises);
    };

    onMounted(async () => {
      await fetchDetails();
      await fetchAssignedStatuses();
    });

    return { details, assignedStatus };
  }
};

模板修改

<tr v-for="(detail, index) in details" :key="index">
  <td class="align-middle">{{ index + 1 }}</td>        
  <td class="align-middle" colspan="3">
    <div v-if="assignedStatus[detail.issues.id]">
         <span class="text-success">Assigned</span>
    </div>
    <div v-else>
         <span class="text-danger">Not Assigned</span>
    </div>
  </td>
</tr>

Vue2 示例代码

export default {
  data() {
    return {
      details: [],
      assignedStatus: {}
    };
  },
  async mounted() {
    await this.fetchDetails();
    await this.fetchAssignedStatuses();
  },
  methods: {
    async fetchDetails() {
      // 替换成你获取details的实际逻辑
      // this.details = await axios.get(...)
    },
    async fetchAssignedStatuses() {
      const promises = this.details.map(item => 
        axios.get(route('issueAssigned', { issueId: item.issues.id }))
          .then(res => {
            // Vue2里需要用$set确保响应式更新
            this.$set(this.assignedStatus, item.issues.id, res.data.isAssigned);
          })
          .catch(err => {
            console.error(err);
            this.$set(this.assignedStatus, item.issues.id, false);
          })
      );
      await Promise.all(promises);
    }
  }
};

方法2:按需加载(适合数据量大的场景)

如果不想一次性加载所有状态,可以给每个issue单独处理加载状态,避免批量请求压力:

Vue3 示例

import { ref, onMounted } from 'vue';
import axios from 'axios';

export default {
  setup() {
    const details = ref([]);
    const assignedStatus = ref({});
    const isLoading = ref({});

    const fetchDetails = async () => {
      // 获取details数据
    };

    // 单独获取某个issue的状态
    const getAssignedStatus = async (issueId) => {
      if (assignedStatus.value.hasOwnProperty(issueId)) return;
      isLoading.value[issueId] = true;
      try {
        const res = await axios.get(route('issueAssigned', { issueId }));
        assignedStatus.value[issueId] = res.data.isAssigned;
      } catch (err) {
        console.error(err);
        assignedStatus.value[issueId] = false;
      } finally {
        isLoading.value[issueId] = false;
      }
    };

    onMounted(async () => {
      await fetchDetails();
    });

    return { details, assignedStatus, isLoading, getAssignedStatus };
  }
};

模板修改

<tr v-for="(detail, index) in details" :key="index">
  <td class="align-middle">{{ index + 1 }}</td>        
  <td class="align-middle" colspan="3">
    <div v-if="isLoading[detail.issues.id]">Loading...</div>
    <div v-else-if="assignedStatus[detail.issues.id]">
         <span class="text-success">Assigned</span>
    </div>
    <div v-else>
         <span class="text-danger">Not Assigned</span>
    </div>
    <!-- 可以在初始化时触发请求,或者点击时触发 -->
    <button v-if="!assignedStatus.hasOwnProperty(detail.issues.id)" @click="getAssignedStatus(detail.issues.id)">
      Check Status
    </button>
  </td>
</tr>

关键提醒

  • 永远不要在模板的v-if、v-show这类指令里直接调用async函数,不仅会导致判断错误,还会在组件每次渲染时重复发起请求,造成性能浪费。
  • 确保状态对象是响应式的(Vue2用$set,Vue3用ref/reactive),这样状态更新时模板会自动重新渲染。

内容的提问来源于stack exchange,提问作者Newbie

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 05:55:06