当前位置: 首页 > news >正文

6.6 Element UI 加载指示器

Element UI 提供了两种主要的加载指示器:

  1. Loading 服务 (Loading Service): 全屏或针对某个 DOM 元素的遮罩层加载。
  2. 组件的 loading 属性: 直接在按钮 (<el-button>) 等组件上设置 loading 属性。

方法一:使用 Loading 服务 (推荐用于全屏或区域加载)

Loading.service(options) 可以创建一个全屏或针对特定元素的加载遮罩。

1. 基本用法 (全屏)
<template><div><el-button type="primary" @click="fetchData">获取数据</el-button><!-- 其他内容 --></div>
</template><script>
import axios from 'axios';
// 引入 Element UI 的 Loading 服务
import { Loading } from 'element-ui';export default {methods: {async fetchData() {let loadingInstance = null;try {// 1. 显示加载loadingInstance = Loading.service({fullscreen: true, // 全屏text: '拼命加载中...', // 加载文本spinner: 'el-icon-loading', // 加载图标background: 'rgba(0, 0, 0, 0.7)' // 遮罩背景色});// 2. 发起 axios 请求const response = await axios.get('/api/some-data');console.log('数据:', response.data);// 3. 请求成功后,可以显示成功消息this.$message.success('数据获取成功!');} catch (error) {// 4. 请求失败,显示错误消息this.$message.error('数据获取失败: ' + (error.message || '未知错误'));} finally {// 5. 无论成功或失败,都必须关闭加载// 使用 $nextTick 确保 DOM 更新后再关闭,避免闪烁this.$nextTick(() => {if (loadingInstance) {loadingInstance.close();}});}}}
}
</script>
2. 针对特定元素的加载 (区域加载)
<template><!-- 给需要加载遮罩的容器添加一个 ref --><div ref="loadingTarget" style="height: 300px; border: 1px solid #ddd; padding: 10px;"><h3>数据列表</h3><el-table :data="tableData" style="width: 100%"><el-table-column prop="name" label="姓名"></el-table-column><el-table-column prop="age" label="年龄"></el-table-column></el-table></div><el-button type="primary" @click="loadTableData">刷新表格</el-button>
</template><script>
import axios from 'axios';
import { Loading } from 'element-ui';export default {data() {return {tableData: []}},methods: {async loadTableData() {let loadingInstance = null;try {// 1. 显示加载,目标是 ref 为 loadingTarget 的元素loadingInstance = Loading.service({target: this.$refs.loadingTarget, // 指定目标 DOM 元素text: '加载中...',spinner: 'el-icon-loading'// fullscreen 为 false 或不设置});// 2. 发起请求const response = await axios.get('/api/table-data');this.tableData = response.data; // 更新数据} catch (error) {this.$message.error('加载表格数据失败');} finally {// 3. 关闭加载this.$nextTick(() => {if (loadingInstance) {loadingInstance.close();}});}}}
}
</script>
3. 封装成可复用的函数

为了减少重复代码,可以将加载逻辑封装起来:

// utils/loading.js
import { Loading } from 'element-ui';// 封装一个带加载的请求函数
export async function requestWithLoading(requestPromise, loadingOptions = {}) {let loadingInstance = null;try {// 合并默认选项const options = {fullscreen: true,text: '加载中...',spinner: 'el-icon-loading',background: 'rgba(0, 0, 0, 0.7)',...loadingOptions};loadingInstance = Loading.service(options);const result = await requestPromise;return result;} catch (error) {// 这里可以根据需要处理错误,或者让调用者处理throw error;} finally {// 确保加载被关闭if (loadingInstance) {// 使用 setTimeout 确保关闭发生在下一个事件循环,避免与组件更新冲突setTimeout(() => {loadingInstance.close();}, 0);}}
}// 在组件中使用
// import { requestWithLoading } from '@/utils/loading';
// import axios from 'axios';// async fetchData() {
//   try {
//     const response = await requestWithLoading(
//       axios.get('/api/data'),
//       { text: '正在查询...', target: this.$refs.someElement } // 可选的自定义 loading 选项
//     );
//     console.log(response.data);
//   } catch (error) {
//     this.$message.error('请求失败');
//   }
// }

方法二:使用组件的 loading 属性 (推荐用于按钮)

当点击按钮发起请求时,直接让按钮进入加载状态是最直观的方式。

<template><div><!-- loading 属性绑定到 data 中的变量 --><el-button type="primary" :loading="loading" @click="handleSubmit">{{ loading ? '提交中...' : '提交' }}</el-button><!-- 对话框中的按钮 --><el-dialog title="编辑" :visible.sync="dialogVisible"><el-form :model="form"><el-form-item label="名称"><el-input v-model="form.name"></el-input></el-form-item></el-form><span slot="footer" class="dialog-footer"><el-button @click="dialogVisible = false">取 消</el-button><el-button type="primary" :loading="dialogLoading" @click="handleDialogSubmit">{{ dialogLoading ? '保存中...' : '确 定' }}</el-button></span></el-dialog></div>
</template><script>
import axios from 'axios';export default {data() {return {loading: false, // 控制主按钮加载状态dialogVisible: false,dialogLoading: false, // 控制对话框内按钮加载状态form: { name: '' }}},methods: {async handleSubmit() {// 1. 设置加载状态this.loading = true;try {// 2. 发起请求await axios.post('/api/submit', this.form);this.$message.success('提交成功!');} catch (error) {this.$message.error('提交失败');} finally {// 3. 无论成功失败,关闭加载this.loading = false;}},async handleDialogSubmit() {this.dialogLoading = true;try {await axios.put(`/api/users/${this.form.id}`, this.form);this.$message.success('保存成功!');this.dialogVisible = false; // 保存成功后关闭对话框} catch (error) {this.$message.error('保存失败');} finally {this.dialogLoading = false;}}}
}
</script>

方法三:结合 axios 拦截器 (全局加载)

如果希望在所有 axios 请求时都显示一个全局加载(比如在页面顶部显示一个进度条或在某个固定区域显示加载),可以使用 axios 的拦截器。

// utils/request.js 或 main.js 中
import axios from 'axios';
import { Loading } from 'element-ui';let loadingInstance = null;
let requestCount = 0; // 请求计数器,防止多个请求时 loading 被过早关闭// 请求拦截器
axios.interceptors.request.use(config => {// 如果是第一个请求,显示加载if (requestCount === 0) {loadingInstance = Loading.service({fullscreen: true,text: '加载中...',spinner: 'el-icon-loading'});}requestCount++;return config;},error => {return Promise.reject(error);}
);// 响应拦截器
axios.interceptors.response.use(response => {requestCount--;// 所有请求都完成时,关闭加载if (requestCount === 0 && loadingInstance) {// 使用 $nextTick 或 setTimeout 确保 DOM 更新setTimeout(() => {loadingInstance.close();loadingInstance = null;}, 0);}return response;},error => {requestCount--;if (requestCount === 0 && loadingInstance) {setTimeout(() => {loadingInstance.close();loadingInstance = null;}, 0);}return Promise.reject(error);}
);// 导出配置好的 axios 实例
export default axios;

注意:

  • 这种方式会影响所有使用这个 axios 实例的请求。
  • 使用 requestCount 计数器是为了处理并发请求。如果第一个请求很快完成而第二个还没完成,不应该关闭加载。
  • 全局拦截器可能不适合所有场景(比如某些请求不需要显示加载),可以在 config 中添加一个自定义标志(如 config.showLoading = false)来控制。

总结与最佳实践

  1. 选择合适的方法:
    • 按钮点击: 优先使用按钮的 loading 属性,用户体验最直接。
    • 页面/区域刷新: 使用 Loading 服务针对特定元素 (target)。
    • 全站通用加载: 考虑使用 axios 拦截器 + Loading 服务(注意并发和可配置性)。
  2. try...catch...finally: 务必在 finally 块中关闭加载,确保无论请求成功或失败,加载状态都能被正确清除。
  3. $nextTick 或 setTimeout: 在关闭 Loading 服务时,使用 this.$nextTick 或 setTimeout(..., 0) 可以避免因 Vue 的异步更新机制导致的加载状态未及时关闭或闪烁的问题。
  4. 用户体验: 设置有意义的加载文本 (text),使用合适的加载图标 (spinner)。
  5. 错误处理: 在 catch 块中处理错误,并给出用户友好的提示(如 this.$message.error())。

通过合理运用这些方法,你可以轻松地在 axios 请求时为用户提供清晰的加载反馈,显著提升应用的交互体验。

http://www.dtcms.com/a/351923.html

相关文章:

  • 机器学习每日一题000-矩阵和向量的乘法python实现
  • Linux SSH 基于密钥交换的自动登录原理简介及配置说明
  • 数据结构第7章 查找(竟成)
  • 在 OpenLayers 中实现自定义右键菜单:基于 vue3-context-menu 的完整指南
  • 河南河北到底以哪条河为界?是黄河还是漳河呢?
  • 你真的了解操作系统吗?
  • 低代码开发实践:快速构建企业采购审批流程的技术方案
  • 无线网络中的Duration字段计算:原理、机制与实现
  • php内存缓存插件yac的安装配置--平替apcu,多进程共享内存
  • 均胜电子上半年毛利率持续提升,汽车智能化与机器人业务多点突破
  • sed流编辑:从ed到现代文本处理的进化
  • 第二篇:MySQL初始化配置与性能优化
  • 汽车零部件软件迭代开发指南
  • Spring Boot -Mybatis的使用和基础
  • 数字孪生:工厂优化的下一个前沿领域
  • GIS开源库汇总
  • Linux笔记10——shell编程基础-4
  • Web安全开发指导规范文档V1.0
  • 基于SpringBoot的美剧观影网站【2026最新】
  • WebSocket 技术详解:协议原理、握手到生产落地的一站式实践
  • AI——提示词工程认识
  • 探索高效随机地址生成器 AddressGen.top
  • STM32——Uinx时间戳+BKP+RTC实时时钟
  • Ubuntu 操作系统
  • 高速CANFD通讯接口芯片ASM1042性能分析与5Mbps多节点测验
  • 进程管理详解
  • 【ElasticSearch】客户端选择
  • Sigma规则集网络安全应用(Elasticsearch、es日志安全检查、SOC、自定义规则)
  • Linux修改服务器时区
  • S2B2B系统哪个好,商淘云、数商云、金蝶云苍穹供应链批发哪个比较靠谱