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

如何在Pinia Store完全加载时通知关联视图?

解决方案:通过Store状态标记加载完成,通知视图显示内容

核心思路是在Store中维护一个加载完成状态,当所有异步请求完成后更新该状态,视图组件通过监听这个状态来切换显示内容(加载提示/实际内容)。


步骤1:修改EquipmentStore,添加加载状态并完善初始化逻辑

在Store中新增响应式状态标记初始化完成,同时优化异步代码写法:

import { ref, computed, watch } from 'vue'
import { defineStore, storeToRefs } from 'pinia'

export const useEquipmentStore = defineStore('EquipmentStore', () => {
    // State variables
    const apiUrl = ref('inject me')
    const equipmentList = ref([])
    // 新增:标记是否初始化完成,初始为false
    const isInitialized = ref(false)
    // 可选:新增错误状态,捕获加载失败场景
    const loadError = ref(null)

    const setApiUrl = (apiUrlValue) => {
        apiUrl.value = apiUrlValue
        return this;
    }

    const fetchEquipmentList = async () => {
        console.log('fetchEquipmentList')
        const url = `${apiUrl.value}Equipment`
        loadError.value = null // 重置错误状态
        try {
            const response = await fetch(url);

            if (!response.ok) {
                throw new Error('Failed to fetch equipment shortlist');
            }

            const result = await response.json();
            equipmentList.value = result.resources;
        } catch (error) {
            console.error('Error fetching equipment shortlist:', error);
            loadError.value = error.message
        }
    }
 
    async function initialize() {
        // 用await替代then,代码更简洁易读
        await Promise.all([fetchEquipmentList()])
        console.log('initialized');
        // 所有请求完成后,标记为已初始化
        isInitialized.value = true
    }

    return {
        apiUrl,
        equipmentList,
        isInitialized, // 暴露状态给视图组件
        loadError, // 可选:暴露错误状态
        initialize,
        setApiUrl,
    }
})

步骤2:在视图组件中根据状态控制内容显示

在条目视图组件里,通过Store的isInitialized状态切换加载提示和实际内容:

<template>
  <!-- 加载中提示 -->
  <div v-if="!isInitialized" class="loading">
    数据加载中,请稍候...
  </div>

  <!-- 加载失败提示 -->
  <div v-else-if="loadError" class="error">
    加载失败:{{ loadError }}
  </div>

  <!-- 加载完成后显示实际内容 -->
  <div v-else class="content">
    <div v-for="item in equipmentList" :key="item.id">
      {{ item.name }}
    </div>
  </div>
</template>

<script setup>
import { useEquipmentStore } from '@/store/EquipmentStore'
import { storeToRefs } from 'pinia'

const equipmentStore = useEquipmentStore()
// 解构出响应式状态
const { equipmentList, isInitialized, loadError } = storeToRefs(equipmentStore)
</script>

可选:等待初始化完成后再挂载应用

如果希望页面完全不显示直到Store加载完成,可修改main.js逻辑,等待初始化完成后再挂载:

// ... 其他代码保持不变
fetch(import.meta.env.BASE_URL + 'config/settings.json')
  .then((response) => response.json())
  .then(async (config) => { // 添加async关键字
    for (const key in config) {
      app.provide(key, config[key])
    }
    const equipmentStore = useEquipmentStore()
    equipmentStore.setApiUrl(config.apiUrl)
    // 等待初始化完成
    await equipmentStore.initialize()
    app.mount('#app')
  })
  .catch((error) => {
    console.error('Error:', error)
  })

这种方式避免了加载过渡,但API请求过慢时页面会长时间空白,需根据业务场景选择。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 16:34:51