Vue 3中如何优雅地实现全局Loading效果并与表格数据交互?

Vue 3中如何优雅地实现全局Loading效果并与表格数据交互?
最新回答
雨后初见彩虹

2020-09-26 20:58:31

在Vue 3中,可通过axios拦截器结合全局状态管理UI库的Loading组件实现优雅的全局Loading效果,并与表格数据交互。以下是具体实现方案:

1. 封装HTTP请求方法

通过axios封装请求,添加loading和notLoading标志位控制Loading显示:

// http.jsimport axios from 'axios';const instance = axios.create({ baseURL: '
https://api.example.com'
, timeout: 5000,});// 请求方法封装export const fetchData = (url, data, options = {}) => { return instance.post(url, data, options);};// 示例:需要Loading的请求export const loadTableData = (data) => fetchData('/api/table', data, { loading: true });// 示例:无需Loading的请求export const getConfig = () => fetchData('/api/config', {}, { notLoading: true });2. 配置axios拦截器

在拦截器中根据标志位控制Loading的显示/隐藏:

// 假设使用Element Plus的ElLoading服务import { ElLoading } from 'element-plus';let loadingInstance = null;instance.interceptors.request.use( (config) => { // 显示Loading的条件:config.loading为true且未设置notLoading if (config.loading && !config.notLoading) { loadingInstance = ElLoading.service({ lock: true, text: '数据加载中...', background: 'rgba(0, 0, 0, 0.7)', }); } return config; }, (error) => { // 请求错误时隐藏Loading if (loadingInstance) { loadingInstance.close(); } return Promise.reject(error); });instance.interceptors.response.use( (response) => { // 请求成功后隐藏Loading if (loadingInstance) { loadingInstance.close(); } return response.data; }, (error) => { // 请求失败时隐藏Loading if (loadingInstance) { loadingInstance.close(); } return Promise.reject(error); });3. 在组件中使用

在表格组件中调用封装好的请求方法,自动触发Loading:

<template> <el-table :data="tableData" style="width: 100%"> <el-table-column prop="name" label="名称" /> <el-table-column prop="value" label="值" /> </el-table></template><script setup>import { ref } from 'vue';import { loadTableData } from '@/http';const tableData = ref([]);const fetchTableData = async () => { try { const res = await loadTableData({ page: 1 }); tableData.value = res.data; } catch (error) { console.error('加载失败:', error); }};// 组件挂载时加载数据fetchTableData();</script>4. 关键点说明
  • 标志位控制:通过config.loading和config.notLoading灵活控制哪些请求需要显示Loading。
  • Loading服务:根据UI库替换ElLoading,例如:

    Ant Design Vue:使用this.$message.loading或Modal.loading。

    自定义组件:通过全局状态(如Pinia)控制Loading的显示。

  • 错误处理:确保拦截器中无论请求成功或失败都关闭Loading,避免卡死。
5. 替代方案:使用Vue 3组合式API

若不想依赖axios拦截器,可通过组合式函数手动控制Loading:

// useLoading.jsimport { ref } from 'vue';export const useLoading = () => { const isLoading = ref(false); const withLoading = async (promise) => { isLoading.value = true; try { const res = await promise; return res; } finally { isLoading.value = false; } }; return { isLoading, withLoading };};

组件中使用

<script setup>import { useLoading } from './useLoading';import { fetchData } from '@/http';const { isLoading, withLoading } = useLoading();const tableData = ref([]);const loadData = async () => { const res = await withLoading(fetchData('/api/table', { page: 1 })); tableData.value = res.data;};</script><template> <el-table v-loading="isLoading" :data="tableData" /></template>总结
  • 推荐方案:基于axios拦截器,适合全局统一管理Loading。
  • 灵活方案:组合式API手动控制,适合需要细粒度控制的场景。
  • UI适配:根据项目使用的UI库(如Element Plus、Ant Design Vue)替换Loading组件。

通过以上方法,可实现Vue 3中全局Loading与表格数据的优雅交互。