uniapp自定义加载组件(q-loading)开发详解
本文详细介绍在uniapp项目中开发自定义加载组件q-loading的过程。涵盖组件目录结构、模板插槽扩展、样式动画编写及Props参数定义,提供圆环、呼吸、旋转三种效果及完整代码示例,帮助开发者快速实现个性化加载提示。
准备工作
当页面接口请求耗时较长时,通过加载页面提示用户内容正在请求中是必要的。接下来将演示如何编写一个简易的自定义加载组件。
在现有的全局组件目录components下创建一个新的组件文件夹,将其命名为q-loading,并创建对应的组件文件q-loading.vue。
选取几款视觉效果良好的CSS加载动画,并对组件样式进行相应调整。
逻辑思路
编写模板部分
为确保组件具备扩展性,利用slot插槽允许插入自定义内容,便于后续进行个性化修改。
通过class和style绑定父组件传递的值,使组件外观更加个性化。
页面布局包含图标和文本提示两部分,两者均支持自定义显示状态、尺寸及颜色。
编写样式部分
该部分主要定义图标和文本的样式,以及加载动画的具体表现。
编写脚本部分
此部分处理父组件传递的参数,通过props进行格式规范与定义。
实战演练
下面将具体实现一个加载组件的完整代码。
模板部分
<view
class="q-loading"
:style="{'backgroundColor': props.bgColor}"
v-if="props.show"
>
<view class="q-loading-inner">
<slot name="load">
<!-- 图标部分 -->
<view
:class="{'q-loading-icon': true, 'pause': !props.show && !props.showIcon}"
v-if="props.showIcon"
>
<slot name="icon">
<!-- 圆环 -->
<view
class="q-loading-item q-loading-circle"
:style="{'width': props.borSize +'rpx', 'height': props.borSize +'rpx', 'borderWidth': props.borWin + 'rpx', 'borderColor': props.borColor, 'borderLeftColor': props.bordActiveColor}"
v-if="props.iconName == 'circle'"
>
</view>
<!-- 呼吸 -->
<view
class="q-loading-item q-loading-circle-breath"
v-if="props.iconName == 'circle-breath'"
>
</view>
<!-- 旋转 -->
<view
class="q-loading-item q-loading-circle-round"
v-if="props.iconName == 'circle-round'"
>
<view
class="loading-round"
:style="{'backgroundColor': props.bordActiveColor}"
></view>
<view
class="loading-round"
:style="{'backgroundColor': props.bordActiveColor}"
></view>
<view
class="loading-round"
:style="{'backgroundColor': props.bordActiveColor}"
></view>
<view
class="loading-round"
:style="{'backgroundColor': props.bordActiveColor}"
></view>
<view
class="loading-round"
:style="{'backgroundColor': props.bordActiveColor}"
></view>
<view
class="loading-round"
:style="{'backgroundColor': props.bordActiveColor}"
></view>
<view
class="loading-round"
:style="{'backgroundColor': props.bordActiveColor}"
></view>
</view>
</slot>
</view>
<!-- 提示文本 -->
<view
class="q-loading-text"
v-if="props.showText"
:style="{'color': props.textColor, 'fontSize': props.textSize + 'rpx'}"
>
<slot name="text"> {{ props.text }} </slot>
</view>
</slot>
</view>
</view>样式部分
这部分定义了页面样式以及对应的三种动画效果。
- 页面的样式
.q-loading {
position: fixed;
top: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
padding: 10rpx;
width: 100%;
height: 100vh;
.q-loading-inner {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.q-loading-icon {
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 10rpx;
width: 100rpx;
height: 100rpx;
.q-loading-circle {
border-radius: 50%;
border-style: solid;
animation: loadingCircle 1s linear infinite;
}
.q-loading-circle-breath {
box-shadow: 0 0 0 0 rgb(204, 73, 152);
height: 36px;
width: 36px;
border-radius: 50%;
animation: loadingCircleBreath 1s linear infinite;
}
.q-loading-circle-round {
position: relative;
width: 75rpx;
height: 75rpx;
.loading-round {
position: absolute;
width: 26rpx;
height: 26rpx;
border-radius: 50%;
animation: loadingCircleRound 3s ease infinite;
transform-origin: 120% 80rpx;
&.loading-round:nth-child(1) {
z-index: 7;
}
&.loading-round:nth-child(2) {
height: 12px;
width: 12px;
animation-delay: 0.2s;
z-index: 6;
}
&.loading-round:nth-child(3) {
height: 11px;
width: 11px;
animation-delay: 0.4s;
z-index: 5;
}
&.loading-round:nth-child(4) {
height: 10px;
width: 10px;
animation-delay: 0.6s;
z-index: 4;
}
&.loading-round:nth-child(5) {
height: 9px;
width: 9px;
animation-delay: 0.8s;
z-index: 3;
}
&.loading-round:nth-child(6) {
height: 8px;
width: 8px;
animation-delay: 1s;
z-index: 2;
}
&.loading-round:nth-child(7) {
height: 7px;
width: 7px;
animation-delay: 1.2s;
z-index: 1;
}
}
}
&.pause {
.q-loading-item {
animation-play-state: paused;
}
}
}
}
}- 三个对应的动画
// 圆环
@keyframes loadingCircle {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
// 呼吸
@keyframes loadingCircleBreath {
0% {
transform: scale(0.3);
box-shadow: 0 0 0 0 rgba(36, 175, 214, 60%);
}
60% {
transform: scale(0.5);
box-shadow: 0 0 0 56rpx rgba(36, 175, 214, 0%);
}
100% {
transform: scale(0.3);
box-shadow: 0 0 0 0 rgba(36, 175, 214, 0%);
}
}
// 转动
@keyframes loadingCircleRound {
to {
transform: rotate(1turn);
}
}脚本部分
这部分定义了传递的数据,包括组件、图标和文本的显示控制,以及各自的颜色、大小等参数。
const props = defineProps({
// 显示加载
show: {
type: Boolean,
default: true,
},
// 背景色
bgColor: {
type: String,
default: "#fff",
},
// 显示图标
showIcon: {
type: Boolean,
default: true,
},
// 名称
iconName: {
type: String,
default: "circle",
},
// 大小
borSize: {
type: Number,
default: 60,
},
// 边框粗细
borWin: {
type: Number,
default: 8,
},
// 颜色
borColor: {
type: String,
default: "#e3e3e3",
},
// 活动颜色
bordActiveColor: {
type: String,
default: "#24afd6",
},
// 显示文本
showText: {
type: Boolean,
default: true,
},
// 文本内容
text: {
type: String,
default: "加载中...",
},
// 文本颜色
textColor: {
type: String,
default: "#555",
},
// 文本大小
textSize: {
type: Number,
default: 20,
},
});效果预览
下面查看实际的预览效果。
圆环效果

呼吸效果

旋转效果

最后
以上是自定义加载组件的主要内容,更多关于uniapp自定义加载组件的资料请关注本站其它相关文章!
JavaScript将图片转换为Base64编码的两种途径
2026-11-05 16:43:05
怎么在 Vue 或 React 项目中正确集成 animate.js
2026-11-05 10:23:38
JS注册事件:addEventListener基础语法与参数详解
2026-11-05 08:44:56
JSP和JS的区别:运行环境与服务端/客户端职责解析
2026-11-04 23:34:36
pdf.js 官方下载地址:GitHub Release 获取预编译包
2026-11-04 23:07:27
