《uni-app》uni-app实现疯狂点赞效果(二) 封装与优化

发布于:2022-12-03 ⋅ 阅读:(259) ⋅ 点赞:(0)

在这里插入图片描述

这是一个没有套路的前端博主,热衷各种前端向的骚操作,经常想到哪就写到哪,如果有感兴趣的技术和前端效果可以留言~博主看到后会去代替大家踩坑的~
主页: oliver尹的主页
格言: 跌倒了爬起来就好~

一. 前言

在上一篇中,我们简单的实现了一个疯狂点赞,或者说是漂浮爱心的效果,但代码也好效果也好,略微有一些些粗糙,有很多地方是可以改进的,这一篇我们主要的目的是为了改进上一篇中的最终成果,使之更符合真实使用~当然,要说这个优化版就是真的项目可使用版么,那也不见得,具体还得根据需求看,毕竟功能做的再好,不符合需求那也是白搭~
本文演示demo使用的UI组件库为uView,如对如何在uni-app中安装uView存在疑惑请浏览博文:《《uni-app》npm详解及在uni-app中对npm的支持
耐心看完,或许所有收获~

二. 阅读对象与难度

本文难度属于:初中级,适合有对uni-app有一定了解的小伙伴,通过本文你可以大致了解以下几个知识点:

  • 组件的封装及使用
  • 利用Promise的特性实现对延迟时间的操作
  • CSS3的animation动画

具体内容可以参考以下的思维导图:
在这里插入图片描述

三. 项目地址与最终效果

文本代码 已上传CSDN上的gitCode,有兴趣的小伙伴可以直接clone,项目地址:https://gitcode.net/zy21131437/uni-app-study

本文最终实现的效果图如下
在这里插入图片描述

四. 具体实现

开始之前先想一想,如果我们要使这个功能更加贴切于实际项目,那么这个效果该怎么优化~
首先,有一点可以确认,这个点赞效果肯定是会被复用的,既然会被复用,那么就必须 组件化,这样的好处是对于组件的BUG我们只需要修改一次,减少代码量等等~
第二个改进,上一篇中虽然我们增加了一定的动画量,但很明显还是达不到那些app的效果,因此我们还需要 增加更多的动画种类来使得漂浮爱心的动画更具有表现力

4.1 组件化修改

组件化修改其实没有那么复杂,说到底,就是把跟点赞漂浮爱心的功能相关的代码完全独立出去,使用的时候我们只需要在对应的位置引入即可,大致示例图如下:
在这里插入图片描述
用代码表示的话,大致就是原来是这种用法:

<!-- 原来的用法 -->
<template>
	<view class="study-container">
		<!-- 输入 -->
		<view class="study-bottom">
			<view class="input-container"><u--input class="input-style" placeholder="请输入内容" border="surround"></u--input></view>

			<view class="likes-container" ref="likeContainer">
				<u-icon v-for="(item, index) in likesData" :class="['icon-default', `${item.animate}`]" :name="item.name" :color="item.color" :key="item.id"></u-icon>

				<u-icon class="icon-style" color="#fc5531" name="heart-fill" @click="createLikes"></u-icon>
			</view>
		</view>
	</view>
</template>

<!-- 还有逻辑代码 -->
<!-- ...... -->

组件化之后,那么使用就改成了组件的方式的引入,而非代码

<!-- 组件化后的用法 -->
<template>
	<view class="study-container">
		<!-- 输入 -->
		<view class="study-bottom">
			<view class="input-container"><u--input class="input-style" placeholder="请输入内容" border="surround"></u--input></view>

			<view class="likes-container" >
        <!-- 引入点赞效果的组件 -->
				<t-likes></t-likes>
			</view>
		</view>
	</view>
</template>

<script>
import TLikes from './likesCom.vue';

export default {
	components: {
		TLikes
	}
};
</script>

至于逻辑代码完全被内置在了 t-likes 这个组件里,与外界不再直接互通~因此,首先我们 新建了一个likesCom.vue 的文件,将之前关于点赞功能的代码全部移入该文件中,功能其实不需要怎么改动,全部移植即可

<template>
	<view class="likes-container">
		<u-icon v-for="(item, index) in likesData" :class="['icon-default', `${item.animate}`]" :name="item.name" :color="item.color" :key="item.id"></u-icon>

		<u-icon class="icon-style" color="#fc5531" name="heart-fill" @click="createLikes"></u-icon>
	</view>
</template>

<script>
import _ from 'lodash';
export default {
	data() {
		return {
			likesData: []
		};
	},
	methods: {
		randomNum(min, max) {
			return Math.floor(Math.random() * (max - min)) + min;
		},
		getLikeParams() {
			// ...原来的获取参数事件
		},
		createLikes: _.throttle(function() {
			// ...原来的点击事件
		}, 10)
	}
};
</script>

<style lang="scss" scoped>
// 原来的样式代码
</style>

这样简单的代码剥离算是完成了,按照预期的期望进行测试,确认效果可以正常触发
在这里插入图片描述
接着,可以在这个上面 再加一些小功能,比如统计一共点击了多少下,那么只需要每一次点击记录一下,再取得总数传递给父组件即可:

export default {
	data() {
		return {
			likesData: [],
			total: 0
		};
	},
	methods: {
		randomNum(min, max) {
			return Math.floor(Math.random() * (max - min)) + min;
		},
		getLikeParams() {},
		createLikes: _.throttle(function() {
			new Promise(reslove => {
				const params = this.getLikeParams();
				this.likesData.push(params);

				this.total += 1;
				// 传递给父组件
				this.$emit('getTotal', this.total);

				setTimeout(() => {
					reslove(params);
				}, 1200);
			}).then(res => {
				this.likesData.shift();
			});
		}, 10)
	}
};
</script>

在父组件中做一个接收,并打印接收值:

<view class="likes-container" >
  <t-likes @getTotal="getTotal"></t-likes>
</view>
<script>
import TLikes from './likesCom.vue';

export default {
	components: {
		TLikes
	},
	methods: {
		getTotal(total) {
			console.log(total);
		}
	}
};
</script>

其表现的效果图如下:
在这里插入图片描述

4.2 实现更多动画

在上一篇中可以知道,上浮动画的核心利用的是CSS3的animation实现 的,大致的动画aanimation值如下:

.icon-animate-1 {
  animation: animate-1 1.5s ease-in-out;
}

@keyframes animate-1 {
  0% {
    top: 20px;
		opacity: 1;
  }

  100% {
    top: -140px;
		opacity: 0;
  }
}

原理我们依旧采用CSS3的animation实现,但这个动画略微有点简单需要稍加改造,改造点主要有三个:

  1. 增加动画的种类,有原来的 5种 增加到 9种
  2. 增加动画的复杂度,原来的 5种 动画实际上 有两种类型,一种是直线往上漂浮,一种是向左/向右+向上漂浮,改造过后 再加入一种贝塞尔曲线速率的动画种类
  3. 增加爱心颜色,原来的 3种 颜色,增加到 7种 颜色,并且色调也稍微改动一下,显得爱心颜色更加柔和;

对于CSS3的animation这里就不全部粘贴了,这里分别对3类动画各选一种分享:
第一种:直线运行
这种最为简单,就是一个简单的上浮动画,CSS代码如下:

.icon-animate-2 {
  animation: animate-2 2.4s ease-in-out;
  animation-fill-mode: forwards;
}
@keyframes animate-2 {
  0% {
    top: 20px;
    opacity: 1;
  }

  100% {
    top: -180px;
    opacity: 0;
  }
}

执行了一个名为 animate-2 的动画,这个 动画持续2.4秒,并且速度是 先加速后减速的效果,动画则是开始距离顶部20像素,透明度为1,动画结束时距离顶部为-180像素,透明度为0,也就是此时已经处于透明状态;
其表现形态的 效果图 如下:
在这里插入图片描述

第二种:直线运行+向左/向右运动
这种动画和第一种 其实是相同原理,区别在于第一种只有改变了 top属性opacity属性,第二种会在第一种的基础上再增加一个 margin-left 或者 margin-right ,示例代码如下:

.icon-animate-4 {
  animation: animate-4 2.4s ease-in-out;
  animation-fill-mode: forwards;
}
@keyframes animate-4 {
  0% {
    top: 20px;
    margin-left: 0;
    opacity: 1;
  }

  100% {
    top: -160px;
    margin-left: -68px;
    opacity: 0;
  }
}

执行了一个名为 animate-4 的动画,这个 动画持续2.4秒,并且速度是 先加速后减速的效果,动画则是开始距离顶部20像素,透明度为1并且距离左侧的距离为0,动画结束时距离顶部为-160像素,透明度为0,距离左侧的距离为-68像素;
其表现形态的 效果图 如下:
在这里插入图片描述

第三种:贝塞尔曲线
这种略微有点复杂,主要复杂在原理,其实放到CSS3种实现就没有那么复杂,简单的说就是 运动的速度遵循贝塞尔曲线的速率公式,CSS3中有现成的公式计算器,如下:

cubic-bezier(0.66, 0.1, 1, 0.41)

类似于这种,这个解释还是有点复杂的,有兴趣的小伙伴可以自行查证,大致如下:

cubic-bezier(x1,y1,x2,y2)

cubic-bezier它接收4个参数,分别是两组平面坐标,起始点(x1,y1),终止点(x2,y2),在这两个点内的速率会按照cubic-bezier这个公式进行实时计算,有时候快,有时候慢~其实有一种animation种类也是遵循这个公式的,就是 ease-in-out,它对应的贝塞尔曲线是

cubic-bezier(0.42,0,0.58,1)

本文中的动画代码如下:

.icon-animate-1 {
  animation: animate-1-left 2.4s ease-in-out, animate-1-top 2.4s cubic-bezier(0.66, 0.1, 1, 0.41);
  animation-fill-mode: forwards;
}
@keyframes animate-1-top {
  0% {
    top: 20px;
    opacity: 1;
  }

  100% {
    top: -200px;
    opacity: 0;
  }
}

@keyframes animate-1-left {
  0% {
    margin-left: 0;
  }

  100% {
    margin-left: -100px;
  }
}

animation执行了两组动画,第一组是向上的一个动画,第二组是一个自定义贝塞尔曲线速率的向左位移变化,动画持续时间都是2.4秒,其表现形态的效果图如下:
在这里插入图片描述
这三种动画各多写几种,最后得到 完整动画效果如下
在这里插入图片描述

五. 小结

本文主要分享了一下 通过CSS3的animation属性,实现了一个疯狂点赞的效果,相比上一篇的效果这一篇完善了很多,并且我们将实现的代码独立成单独的一个 .vue文件,形成了一个组件这样就解决了复用代码的问题,当然还是那句话,CSS3的实现并非最优解,还有很多其他方式也可以实现,至少canvas实现的效果肯定比CSS3来的好~