在 uniapp 里,`uni.request`中`showLoading: true/false`控制的加载动画,本质是调用了`uni.showLoading`和`uni.hideLoading`这两个 API,其默认的加载动画样式是由 uniapp 框架以及运行平台(如微信小程序、App 等)决定的。若想替换这个默认动画,可按以下步骤操作:
### 一、理解默认加载逻辑
当在`uni.request`里设置`showLoading: true`时,uniapp 会自动调用`uni.showLoading`显示默认加载提示;请求结束(成功或失败)后,若设置`showLoading: false`(或框架自动处理),会调用`uni.hideLoading`隐藏。默认加载动画的样式,不同平台呈现不同(比如微信小程序是特定样式的转圈,App 端也有其默认表现 )。
### 二、替换思路与实现方法
#### 方案 1:自定义全局加载组件,替代默认`uni.showLoading`
1. **封装自定义加载组件**
在项目的`components`目录,新建类似`custom-loading.vue`的组件,示例代码:
html
~~~html
<template>
<view class="custom-loading-mask" v-show="show">
<!-- 这里放自定义的加载动画内容,比如 GIF 图、自定义动画 -->
<image class="loading-img" :src="loadingImg"></image>
<text class="loading-text">{{loadingText}}</text>
</view>
</template>
<script>
export default {
data() {
return {
show: false,
loadingImg: "/static/custom-loading.gif", // 自定义加载图,需放到 static 目录
loadingText: "加载中..."
};
},
methods: {
showLoading(text = "加载中...") {
this.loadingText = text;
this.show = true;
},
hideLoading() {
this.show = false;
}
}
};
</script>
<style scoped>
.custom-loading-mask {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(255, 255, 255, 0.8); /* 遮罩背景,可按需调整 */
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
z-index: 9999; /* 保证层级最高 */
}
.loading-img {
width: 80rpx;
height: 80rpx;
}
.loading-text {
margin-top: 20rpx;
font-size: 28rpx;
}
</style>
~~~
2. **全局注册并管理组件状态**
在`App.vue`里引入并注册,通过全局变量或事件总线来控制显示隐藏:
html
~~~html
<template>
<view class="app">
<custom-loading ref="customLoading"></custom-loading>
<router-view></router-view>
</view>
</template>
<script>
import customLoading from "@/components/custom-loading.vue";
export default {
components: {
customLoading
},
globalData: {
customLoading: null
},
onLaunch() {
// 把组件实例挂载到全局,方便其他页面调用
this.globalData.customLoading = this.$refs.customLoading;
// 也可用事件总线方式(更灵活)
uni.$on("showCustomLoading", (text) => {
this.$refs.customLoading.showLoading(text);
});
uni.$on("hideCustomLoading", () => {
this.$refs.customLoading.hideLoading();
});
}
};
</script>
~~~
3. **改造`uni.request`,替换默认加载**
在封装的`request.js`里(若没封装,建议先封装统一管理请求 ),拦截请求,用自定义加载替代默认`showLoading`。示例(假设已封装请求类):
js
~~~js
class Http {
constructor() {
// 其他初始化逻辑...
}
request(options) {
// 显示自定义加载
uni.$emit("showCustomLoading", options.loadingText || "加载中...");
return new Promise((resolve, reject) => {
uni.request({
...options,
success: (res) => {
resolve(res);
},
fail: (err) => {
reject(err);
},
complete: () => {
// 请求完成,隐藏自定义加载
uni.$emit("hideCustomLoading");
}
});
});
}
}
export default new Http();
~~~
这样,每次发起请求时,就会显示自定义的加载组件,而非默认动画。
#### 方案 2:修改默认`uni.showLoading`样式(部分平台有限支持 )
有些平台(如微信小程序 ),可通过修改`app.json`(对应 uniapp 里的`manifest.json`小程序配置 )尝试调整加载样式,但局限性大,且不同平台效果差异明显。以微信小程序为例,在`manifest.json`的`mp-weixin`节点添加:
json
~~~json
{
"mp-weixin": {
"loading": {
"title": "自定义加载文字",
"mask": true,
// 部分版本/场景下,尝试自定义样式(实际支持度有限)
"image": "/static/custom-loading.png"
}
}
}
~~~
不过这种方式,很多平台并不支持自定义加载图,仅能改文字、是否显示遮罩,所以**优先推荐方案 1(自定义组件)**。
#### 方案 3:利用请求拦截器统一控制(结合方案 1 )
借助 uniapp 的`uni.addInterceptor`拦截`request`,在请求开始时显示自定义加载,结束时隐藏。示例:
js
~~~js
// 在 main.js 或请求封装文件里
uni.addInterceptor('request', {
invoke(config) {
// config 里可拿到是否传了 showLoading,或自己扩展参数
if (config.showLoading !== false) {
// 显示自定义加载,可通过事件总线通知
uni.$emit("showCustomLoading", "加载中...");
}
},
complete(res) {
// 请求完成,隐藏自定义加载
uni.$emit("hideCustomLoading");
}
});
~~~
同时,要确保在`App.vue`里已注册好自定义加载组件并监听事件,这样所有通过`uni.request`的请求,都会被拦截并替换加载动画。
### 三、总结
想替换`uni.request`中`showLoading`控制的默认动画,**最佳方式是封装自定义加载组件**,通过全局状态管理(如`globalData`、事件总线 )或请求拦截器,在请求开始时显示自定义组件,结束时隐藏。这样能完全自定义加载动画的样式(如用 GIF、CSS 动画等 ),适配不同业务需求,也能跨平台统一效果。
如果项目已封装请求,直接在请求的`before`和`after`逻辑里替换默认`showLoading`为自定义组件的显示隐藏即可;若没封装,先封装请求统一管理,再按上述步骤改造,就能轻松替换加载动画啦~
