Vue 中使用 Element Plus 实现全局 Loading 效果并封装为高阶函数

在现代前端开发中,全局加载效果是一个常见需求。用户在进行异步操作(如网络请求)时,为了提升体验,通常希望有一个加载动画来指示正在进行的后台操作。本篇博客将介绍如何使用 Element PlusElLoading 组件来实现全局加载动画,并将其封装为一个高阶函数以便复用。

开发环境

本文使用的技术栈如下:

  • Vue 版本3.x
  • Element Plus 版本2.x

你可以使用以下命令安装 Vue 和 Element Plus:.

npm install vue
npm install element-plus

1. 引入 Element Plus 的 ElLoading 组件

在项目中,我们首先需要引入 Element Plus 提供的 ElLoading 组件。ElLoading 是一个服务,它可以帮助我们轻松地显示加载动画。

import { ElLoading } from 'element-plus';

2. 创建加载动画的显示与隐藏方法

我们先定义两个方法:一个用于显示加载动画,另一个用于隐藏加载动画。这样可以在不同场景下灵活调用。

let loadingInstance = null; // 存储当前的加载实例

// 显示加载动画
const showLoading = (options = {}) => {
  if (!loadingInstance) {
    loadingInstance = ElLoading.service({
      lock: true, // 锁定屏幕,防止用户在加载过程中进行其他操作
      text: options.text || '加载中...', // 自定义加载提示文本
      background: options.background || 'rgba(0, 0, 0, 0.7)', // 自定义背景颜色
      spinner: options.spinner || null, // 自定义加载动画(可选)
      fullscreen: true, // 全屏模式
    });
  }
};

// 隐藏加载动画
const hideLoading = () => {
  if (loadingInstance) {
    loadingInstance.close(); // 关闭加载动画
    loadingInstance = null; // 重置实例
  }
};
说明:
  • loadingInstance:这是一个全局变量,用来保存当前的加载动画实例,以便在需要时关闭。
  • showLoading:这个函数用于显示加载动画,支持自定义文本、背景颜色、动画样式等。
  • hideLoading:用于关闭加载动画。

3. 封装为高阶函数

为了使加载动画能够在任何异步操作中复用,我们将其封装为一个高阶函数。这个高阶函数会在执行异步操作前显示加载动画,异步操作完成或出错后关闭动画。

export const withLoading = (fn, options = {}) => {
  const newFn = async (...args) => {
    try {
      showLoading(options); // 开始加载动画
      const result = await fn(...args); // 执行异步操作
      hideLoading(); // 完成后隐藏加载动画
      return result; // 返回结果
    } catch (err) {
      hideLoading(); // 出现错误时也要隐藏动画
      throw err; // 抛出错误给调用方处理
    }
  };
  return newFn; // 返回封装后的新函数
};
说明:
  • withLoading 是一个高阶函数,它接收一个异步函数 fn 作为参数,并在异步操作执行前后控制加载动画的显示与隐藏。
  • 通过 options 参数,我们可以灵活定制加载动画的文本、背景等配置。

4. 示例:在 Vue 组件中使用 withLoading

在 Vue 3 中,我们可以使用 withLoading 包裹异步函数,并在组件内通过按钮触发该函数。

使用 <script lang="ts" setup> 语法的示例:

<template>
  <div>
    <button @click="handleFetchData">加载数据</button>
  </div>
</template>

<script lang="ts" setup>
import { withLoading } from './hooks/loading';

// 模拟异步请求函数
const fetchData = async (): Promise<string> => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve('数据加载成功');
    }, 2000); // 模拟2秒的网络延迟
  });
};

// 使用高阶函数包裹 fetchData
const fetchDataWithLoading = withLoading(fetchData, { text: '数据加载中...' });

// 按钮点击事件处理函数
const handleFetchData = async () => {
  try {
    const data = await fetchDataWithLoading();
    console.log(data); // 输出“数据加载成功”
  } catch (error) {
    console.error('加载失败', error);
  }
};
</script>
说明:
  • <script setup> 中,我们直接定义了函数 handleFetchData,用于在点击按钮时触发异步加载操作。
  • fetchData 是模拟的异步函数,通过 withLoading 包裹后,会在其执行前后自动管理加载动画。

5. 使用 export default 的 Vue 组件示例

如果你使用传统的 export default 风格,以下是一个完整的 Vue 组件示例:

<template>
  <div>
    <button @click="handleFetchData">加载数据</button>
  </div>
</template>

<script>
import { withLoading } from './hooks/loading';

export default {
  name: 'LoadingExample',
  setup() {
    const fetchData = async () => {
      // 模拟异步请求
      return new Promise((resolve) => {
        setTimeout(() => {
          resolve('数据加载成功');
        }, 2000);
      });
    };

    const fetchDataWithLoading = withLoading(fetchData, { text: '数据加载中...' });

    const handleFetchData = async () => {
      try {
        const data = await fetchDataWithLoading();
        console.log(data); // 输出加载结果
      } catch (err) {
        console.error('加载失败', err); // 错误处理
      }
    };

    return {
      handleFetchData,
    };
  },
};
</script>
说明:
  • 我们在 setup 函数中定义了 fetchData 并用 withLoading 包裹它。
  • 通过点击按钮调用 handleFetchData,异步操作会自动展示加载动画并在操作完成后隐藏。

6. 总结

本文展示了如何使用 Element Plus 的 ElLoading 组件实现全局加载动画,并通过高阶函数封装,让我们可以在不同的异步操作中方便地使用这个功能。这样的封装使得代码更加简洁和易维护,同时提升了用户体验。

完整代码可以在你的项目中复用,且可以通过自定义参数适应不同的场景需求。

希望这篇文章对你有所帮助!

参考链接

【手把手】Element UI&Plus里Loading的极致封装!只需0.5行超简洁使用 - 知乎 (zhihu.com)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值