Vue项目里的Loading状态管理:一个基于Pinia的简洁方案

更新日期: 2026-04-24 阅读: 14 标签: Pinia

做Vue项目的时候,大家肯定都碰到过loading状态管理这个麻烦事。一个页面要调三个接口,你怎么写loading?像下面这样?

const loading1 = ref(false)
const loading2 = ref(false)
const loading3 = ref(false)

然后三个地方分别控制。这种做法太土了。要么全屏loading闪来闪去,要么页面上一堆loading各管各的,看起来乱得很。

今天说一个我们项目里正在用的方案。用了Pinia,也就一百行代码,体验好很多。


核心思路

让组件自己上报,让store统一调度。

具体来说:每个组件只管自己的loading状态,然后告诉全局store说"我在加载"。store负责监听所有组件的状态,只要还有一个组件在加载,就保持全屏loading。

这样做有几个好处:

  • 组件逻辑干净,不用关心别人是不是也在加载

  • 多个请求自动合并成一个loading展示

  • 组件卸载时自动清理,不会内存泄漏


代码实现

先看store部分,核心代码也就几十行:

// loading-store.js
import { defineStore } from 'pinia'
import { ref, computed, watch, toValue } from 'vue'
import { ElLoading } from 'element-plus'

export const useLoadingStore = defineStore('loading', () => {
    // 存所有组件的loading状态
    const loadingSources = ref([])
    
    // 组件用这个注册自己
    const addLoadingSource = (source) => {
        loadingSources.value.push(source)
    }
    
    // 组件卸载时移除
    const removeLoadingSource = (source) => {
        const index = loadingSources.value.indexOf(source)
        if (index > -1) {
            loadingSources.value.splice(index, 1)
        }
    }
    
    // 只要有一个组件在loading,就返回true
    const isLoading = computed(() =>
        loadingSources.value.some(source => toValue(source))
    )
    
    let loadingInstance = null
    
    // 监听变化,自动显示或隐藏
    watch(isLoading, (loading) => {
        if (loading) {
            // 显示全屏loading
            if (!loadingInstance) {
                loadingInstance = ElLoading.service({ fullscreen: true })
            }
        } else {
            // 所有加载都完成了,关闭
            if (loadingInstance) {
                loadingInstance.close()
                loadingInstance = null
            }
        }
    })
    
    return { addLoadingSource, removeLoadingSource }
})

再看组件里怎么用:

<script setup>
import { ref } from 'vue'
import { onBeforeUnmount } from 'vue'
import { useLoadingStore } from './loading-store'

const loadingStore = useLoadingStore()
const myLoading = ref(false) // 自己的loading状态

// 注册一下,告诉store"我的状态你帮忙盯着"
loadingStore.addLoadingSource(myLoading)

const fetchData = async () => {
    myLoading.value = true
    try {
        await api.getData()
    } finally {
        myLoading.value = false
    }
}

// 组件卸载时记得清理
onBeforeUnmount(() => {
    loadingStore.removeLoadingSource(myLoading)
})
</script>

组件完全不用管全局的loading怎么显示隐藏,只管自己的myLoading.value = true或false就行。其他的store全帮你搞定。


这个方案好在哪

自动合并请求

比如页面同时发三个请求,三个组件都把loading设为true,但全屏loading只出现一次。最后一个请求结束,loading才消失。

组件卸载自动清理

组件销毁了,它的loading状态还留在store里怎么办?在onBeforeUnmount里移除注册就行,这是个好习惯。

支持各种loading形式

上面用了toValue,这是VueUse里的工具函数,能处理ref、computed、普通值和getter函数。所以你的loading状态可以这样写:

// 都可以
const loading = ref(false)
const loading = computed(() => someCondition)
const loading = () => isLoading.value

可扩展性强

如果想加个最小显示时间(防止loading一闪而过),或者想区分页面loading和局部loading,在store里加逻辑就行,组件完全不用改。


总结

这个方案的核心就是让组件只关心自己的事,全局的事交给store。代码不多,但用起来顺手,推荐你试试。

本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!

链接: https://fly63.com/article/detial/13707

相关推荐

测试一下Pinia,Vuex 要出局了?

自从我开始使用Vue 3和组合API以来,我也尝试使用 Pinea 作为状态管理库。如果是从是 vue2 和 vuex 过来的,就会觉得用起来差别还是很大的。

全新的 Vue3 状态管理工具:Pinia

Vue3 发布已经有一段时间了,它采用了新的响应式系统,而且构建了一套全新的 Composition API。Vue 的周边生态都在加紧适配这套新的系统,官方的状态管理库 Vuex 也在适配中

快速入门Pinia状态管理库

Pinia 是一个用于 Vue 的状态治理库,相似 Vuex, 是 Vue 的另一种状态治理计划。如果你现在使用 vue3 开发项目,那么推荐你使用 Pinia 开发。

Vue新一代状态管理插件Pinia

如果你之前使用过 vuex 进行状态管理的话,那么 pinia 就是一个类似的插件。它是最新一代的轻量级状态管理插件。按照尤雨溪的说法,vuex 将不再接收新的功能,建议将 Pinia 用于新的项目。

Pinia是Vuex的良好替代品吗?

Pinia 是 Vue.js 的轻量级状态管理库,最近很受欢迎。它使用 Vue 3 中的新反应系统来构建一个直观且完全类型化的状态管理库。

Pinia被鼓吹的setup写法真的好用吗

引用官方的一句话:Pinia是一个符合直觉的 Vue.js 状态管理库。简单说几点它的特性:它支持Vue3,同时也支持Vue2,是Vuex的完美过渡替代者

一文解析 Pinia 和 Vuex ,带你全面理解这两个 Vue 状态管理模式

Pinia和Vuex一样都是是vue的全局状态管理器。其实Pinia就是Vuex5,只不过为了尊重原作者的贡献就沿用了这个看起来很甜的名字Pinia。本文将通过Vue3的形式对两者的不同实现方式进行对比,让你在以后工作中无论使用到Pinia还是Vuex的时候都能够游刃有余。

我使用 Pinia 的 5 大技巧

在这篇文章中,想与大家分享使用 Pinia 的五大技巧。以下是简要总结:不要创建无用的 getter,在 Option Stores 中使用组合式函数(composables),对于复杂的组合式函数,使用 Setup Stores

Pinia 3.0 正式发布,不再支持 Vue 2

Vue 官方推荐的状态管理工具 Pinia 最近更新到了 3.0 版本。这个版本有一个最重要的变化:它彻底放弃了对 Vue 2 的支持,现在只专注于 Vue 3 的生态。

Vue状态管理:Pinia与Vuex全面对比

在Vue应用开发中,随着项目规模的增长,组件之间的数据共享变得越来越复杂。状态管理工具就是为了解决这个问题而出现的。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!