前言

在小程序的开发中,页面的加载过程可能会因为网络状况的不好或数据量的过大而显得非常缓慢,这时候加上一个加载动画就能有效的缓解用户的等待焦虑感。而对于应用的多个页面来说,使用全局加载动画可以提高用户体验,让应用显得更加美观和专业。
本篇技术分享博客将为大家介绍在小程序中封装全局加载动画的具体实现步骤,帮助您提高小程序的用户体验。

效果

小程序 keyframes 动画在ios端卡顿 小程序加载动画_小程序

思路

封装全局加载动画的核心思路就是在每个页面加载数据时弹出加载动画,在数据加载完成后关闭动画。由于需要在所有页面中使用,我们需要将加载动画封装成一个全局组件,供所有页面调用。

具体实现步骤

第一步:创建Loading组件

我们新建一个Loading组件,用来展示动画,并在组件中实现开启和结束动画的方法。

wxml代码:

<view class='loading-mask'  wx:if="{{showLoading}}">
    <view class="container">
      <view class="box">
        <view class="atom"></view>
        <view class="atom"></view>
        <view class="atom"></view>
        <view class="dot"></view>
      </view>
    </view>
  </view>

js代码:

Component({
  /**
   * 组件的属性列表
   */
  properties: {
    // 是否显示loading
    showLoading: {
      type: Boolean,
      value: false
    }
  },
  /**
   * 组件的方法列表
   */
  methods: {
    // 开启动画
    show() {
      this.setData({showLoading: true});
    },
    // 关闭动画
    hide() {
      this.setData({showLoading: false});
    }
  }
});

//CSS样式

container {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
}
.box {
	position: relative;
	width: 120rpx;
	height: 120rpx;
}
.dot{
	position: absolute;
	width: 10px;
	height: 10px;
	border-radius: 50%;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	background-color: #9eff03;
	animation: dotbreath 2s linear infinite;
}
.atom {
	position: absolute;
	width: 100%;
	height: 100%;
	border-radius: 50%;
	border-left-width: 6rpx;
	border-top-width: 6rpx;
	border-left-color: #20ff03;
	border-left-style: solid;
	border-top-style: solid;
	border-top-color: transparent;
	
}
.atom:nth-of-type(1) {
	left: 0%;
	top: 0%;
	animation: atom1 1s linear infinite;
}
.atom:nth-of-type(2) {
	right: 0%;
	top: 0%;
	animation: atom2 1s linear infinite;
}
.atom:nth-of-type(3) {
	right: 0%;
	bottom: 0%;
	animation: atom3 1s linear infinite;
}
@keyframes dotbreath {
	0% {
		opacity:1;
	}
	
	50%{
		opacity:0.5;
	}
	100%{
		opacity:1;
	}
}
@keyframes atom1 {
	0% {
		transform: rotateZ(120deg) rotateX(66deg) rotateZ(0deg);
	}
	100% {
		transform: rotateZ(120deg) rotateX(66deg) rotateZ(360deg);
	}
}
@keyframes atom2 {
	0% {
		transform: rotateZ(240deg) rotateX(66deg) rotateZ(0deg);
	}
	100% {
		transform: rotateZ(240deg) rotateX(66deg) rotateZ(360deg);
	}
}

@keyframes atom3 {
	0% {
		 transform: rotateZ(360deg) rotateX(66deg) rotateZ(0deg);
	}
	100% {
		 transform: rotateZ(360deg) rotateX(66deg) rotateZ(360deg);
	}
}
.loading-mask {
  height: 170rpx;
  position: fixed;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.4);
  z-index: 100;
}
第二步:在app.js中加载Loading组件

在App.js中加载自定义组件Loading,并设定全局方法showLoading和hideLoading来显示和隐藏Loading组件。
js代码:

App({
  onLaunch: function () {
    // 加载Loading组件
    this.globalData.loading = this.selectComponent("#loading");
  },
  // 显示加载动画
  showLoading() {
    this.globalData.loading && this.globalData.loading.show();
  },
  // 隐藏加载动画
  hideLoading() {
    this.globalData.loading && this.globalData.loading.hide();
  }
});
第三步:在需要用到加载动画的地方调用全局方法

在需要用到加载动画的地方,通过调用App.js中的showLoading方法显示Loading动画,并在数据加载完毕后调用hideLoading方法关闭Loading动画。

js代码:

// 在页面中显示Loading动画
App.showLoading();

// 在数据请求成功回调中隐藏Loading动画
wx.request({
  url: 'url',
  success: function(res) {
    // 数据请求成功
    App.hideLoading();
  }
})

闭坑指南

在实际开发过程中,可能会遇到一些坑。我们需要注意以下几点:

  1. 组件命名
    在命名组件时要避免与已有的组件重名,以免命名冲突导致组件无法正常使用。
  2. 全局方法
    为确保全局方法生效,应在App.js中定义全局方法,并在需要调用的地方使用App.xxx()方法进行调用。
  3. 加载动画的选择
    在选择动画样式时,应根据产品需求和用户体验进行选择,以实现最好的效果,如果不喜欢这个Loading效果,可以在这里小程序加载动画找找其他的动画效果。

完整代码示例

完整代码示例如下:

//app.js
App({
  onLaunch: function () {
    // 加载Loading组件
    this.globalData.loading = this.selectComponent("#loading");
  },

  // 显示加载动画
  showLoading() {
    this.globalData.loading && this.globalData.loading.show();
  },

  // 隐藏加载动画
  hideLoading() {
    this.globalData.loading && this.globalData.loading.hide();
  }
});
/**loading.wxml**/
<view class='loading-mask' wx:if="{{showLoading}}">
  <view class='loading-content'>
    <image class='loading-image' src='../../images/loading.gif'></image>
    <view class='loading-text'>加载中...</view>
  </view>
</view>
//loading.js
Component({
  /**
   * 组件的属性列表
   */
  properties: {
    // 是否显示loading
    showLoading: {
      type: Boolean,
      value: false
    }
  },

  /**
   * 组件的方法列表
   */
  methods: {
    // 开启动画
    show() {
      this.setData({showLoading: true});
    },
    // 关闭动画
    hide() {
      this.setData({showLoading: false});
    }
  }
});

页面部分

<view>
  <!--其他页面内容-->
  <Loading id="loading"></Loading>
</view>

js部分

// 在页面中显示Loading动画
App.showLoading();
// 在数据请求成功回调中隐藏Loading动画
wx.request({
  url: 'url',
  success: function(res) {
    // 数据请求成功
    App.hideLoading();
  }
})

样式部分

container {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
}
.box {
	position: relative;
	width: 120rpx;
	height: 120rpx;
}
.dot{
	position: absolute;
	width: 10px;
	height: 10px;
	border-radius: 50%;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	background-color: #9eff03;
	animation: dotbreath 2s linear infinite;
}
.atom {
	position: absolute;
	width: 100%;
	height: 100%;
	border-radius: 50%;
	border-left-width: 6rpx;
	border-top-width: 6rpx;
	border-left-color: #20ff03;
	border-left-style: solid;
	border-top-style: solid;
	border-top-color: transparent;
	
}
.atom:nth-of-type(1) {
	left: 0%;
	top: 0%;
	animation: atom1 1s linear infinite;
}
.atom:nth-of-type(2) {
	right: 0%;
	top: 0%;
	animation: atom2 1s linear infinite;
}
.atom:nth-of-type(3) {
	right: 0%;
	bottom: 0%;
	animation: atom3 1s linear infinite;
}
@keyframes dotbreath {
	0% {
		opacity:1;
	}
	
	50%{
		opacity:0.5;
	}
	100%{
		opacity:1;
	}
}
@keyframes atom1 {
	0% {
		transform: rotateZ(120deg) rotateX(66deg) rotateZ(0deg);
	}
	100% {
		transform: rotateZ(120deg) rotateX(66deg) rotateZ(360deg);
	}
}
@keyframes atom2 {
	0% {
		transform: rotateZ(240deg) rotateX(66deg) rotateZ(0deg);
	}
	100% {
		transform: rotateZ(240deg) rotateX(66deg) rotateZ(360deg);
	}
}

@keyframes atom3 {
	0% {
		 transform: rotateZ(360deg) rotateX(66deg) rotateZ(0deg);
	}
	100% {
		 transform: rotateZ(360deg) rotateX(66deg) rotateZ(360deg);
	}
}
.loading-mask {
  height: 170rpx;
  position: fixed;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.4);
  z-index: 100;
}

总结

通过上述步骤,我们就完成了小程序中封装全局加载动画的具体实现方法。在实际开发中,我们可以根据实际需求对组件样式和方法进行调整和修改,以满足不同的开发需求。