android点赞功能实现 app点赞功能怎么实现_uni-app

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


《uni-app》uni-app实现疯狂点赞效果(一)实现

  • 一. 前言
  • 二. 阅读对象与难度
  • 三. 项目地址与最终效果
  • 四. 实现
  • 4.1 简单布个局
  • 4.2 实现上浮动画
  • 4.3 加入点击事件
  • 4.4 稍微优化一下
  • 五. 小结


一. 前言

现在很多app尤其是直播类、视频类甚至是社交类的,基本都是带有 “点赞功能”,其中有一部分app的点赞功能甚至可以被称为是 “疯狂点赞”,大量的爱心漂浮功能感觉非常有意思,忍不住尝试一下其实现~当然本文的实现仅仅是demo级别的,下一篇我们再进一步做优化,本文先用CSS实现效果再说~
本文演示demo使用的UI组件库为:uView,它可以协助我们快速布局以及使用其一些组件,如对如何在uni-app中安装uView存在疑惑请浏览博文:《《uni-app》npm详解及在uni-app中对npm的支持》
耐心看完,或许所有收获~

二. 阅读对象与难度

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

  • CSS中的动画animation属性及其用法
  • 利用Promise的特性实现对延迟时间的操作

具体内容可以参考以下的思维导图:

android点赞功能实现 app点赞功能怎么实现_点赞效果_02

三. 项目地址与最终效果

文本代码已上传上的gitCode,有兴趣的小伙伴可以直接clone,项目地址:https://gitcode.net/zy21131437/uni-app-study 本文最终实现的效果图如下:

android点赞功能实现 app点赞功能怎么实现_前端_03

四. 实现

4.1 简单布个局

由于我们只是为了探索实现点赞效果,因此template部分,也就是Html部分就简单布局一下了,大致布局的示意图如下:

android点赞功能实现 app点赞功能怎么实现_前端_04


具体代码如下:

<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 class="icon-style" color="#fc5531" name="heart-fill"></u-icon>
			</view>
		</view>
	</view>
</template>

简单的盒模型,通过 view标签 的嵌套实现了简单布局,最终实现的布局效果大致如下

android点赞功能实现 app点赞功能怎么实现_点赞效果_05

其中这一段中最主要的是这一段代码:

<u-icon class="icon-style" color="#fc5531" name="heart-fill"></u-icon>

我们的目的是需要 实现点击后的大量带有上浮动画的爱心,那么这一段代码就是 必须包含点击事件,用于触发点击事件,绑定事件的语法遵循vue的语法

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

<script>
export default {
	methods: {
		createLikes() {
      		console.log("触发点击")
		}
	}
};
</script>

4.2 实现上浮动画

上浮动画的核心利用的是CSS3的animate实现 的,先来个简单的上浮

.icon-animate-1 {
  animation: animate-1 1.5s ease-in-out;
}
@keyframes animate-1 {
  0% {
    top: 20px;
		opacity: 1;
  }
  100% {
    top: -140px;
		opacity: 0;
  }
}

解释一下这段代码,有一个类名 icon-animate-1 ,这个类名中有一个 animation属性,它是隶属于CSS3中新增的一个属性,主要的作用是执行动画,这里它执行了一个名为 animate-1 的动画,动画持续时间为 1.5s,动画的运动速度为 ease-in-out(动画以低速开始和结束)

接着是 @keyframes animate-1,定义了一个动画,大致意思是开始的时候top的值为20px,当动画结束的时候top的值为-140px,当定义完,把类名加到Icon组件上,它就会实现一个动画,动画大致是这样的效果:

android点赞功能实现 app点赞功能怎么实现_uni-app_06


是不是有那么点意思了,既然单个动画实现了,那么接下来就是动态添加了,我们必须在 点击爱心的时候才触发这个动态效果,而不是一加载页面就立刻触发~

4.3 加入点击事件

接入上面的代码,我们在一开始的时候就为爱心的图标加入了 点击事件,如下:

<script>
export default {
	methods: {
		createLikes() {
      console.log("触发点击")
		}
	}
};
</script>

为了配合这段代码,我们 需要加入icon组件以及循环生成icon组件的变量,加入组件后的代码如下:

<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>
<script>
import _ from 'lodash';
export default {
	data() {
		return {
			likesData: []
		};
	},
	methods: {
		createLikes() {
      console.log("触发点击")
		}
	}
};
</script>

通过触发点击事件,将生成的参数push进likesData利用vue的v-for指令循环生成DOM,当DOM被渲染出来之后,立刻触发CSS样式中的 animation动画,大致流程如下:

android点赞功能实现 app点赞功能怎么实现_uni-app实现点赞效果_07

第一步事件触发已经完成,就是绑定在DOM上的点击事件,接着是 第二步创建配置参数
先说说配置参数的作用,主要作用其实就两个:

  • ICON组件上附加的类名,这个是重要的,这个类名直接关系到这个icon组件执行的animation动画究竟是哪个;
  • ICON组件的颜色,也就是漂浮爱心的颜色,因为按照那些app上的漂浮爱心显示,颜色明显是不一样的,具有一定的随机性,因此这里也要随机显示;

这两个参数都需要 随机显示,因此在写配置函数之前要有一个 生成随机数的函数

<script>
export default {
	methods: {
		randomNum(min, max) {
			return Math.floor(Math.random() * (max - min)) + min;
		},
    getLikeParams(){}
	}
};
</script>

这里简单的利用了原生的方法,实现了一个 随机数生成的函数,之后利用随机数生成函数可以获得 随机的类名颜色

<script>
export default {
	methods: {
		randomNum(min, max) {
			return Math.floor(Math.random() * (max - min)) + min;
		},
    getLikeParams(){
      const classList = ['icon-animate-1'];
			const colorList = ['#fc5531', '#fcd030', '#00ff7f'];

			const className = classList[this.randomNum(0, classList.length)];
			const colorName = colorList[this.randomNum(0, colorList.length)];

			return {
				animate: className,
				color: colorName,
				name: 'heart-fill',
				id: `${new Date().getTime()}-likes`
			};
    }
	}
};
</script>

这样,每一次点击的时候,我们都可以得到一个 相对随机的参数配置
接着,我们需要 将参数配置push进likesData数组中v-for执行就会立刻执行循环生成DOM渲染进页面了

<script>
export default {
	methods: {
    createLikes() {
      const params = this.getLikeParams();
      // push参数
      this.likesData.push(params);
		},
		randomNum(min, max) {
			return Math.floor(Math.random() * (max - min)) + min;
		},
    getLikeParams(){
      const classList = ['icon-animate-1'];
			const colorList = ['#fc5531', '#fcd030', '#00ff7f'];

			const className = classList[this.randomNum(0, classList.length)];
			const colorName = colorList[this.randomNum(0, colorList.length)];

			return {
				animate: className,
				color: colorName,
				name: 'heart-fill',
				id: `${new Date().getTime()}-likes`
			};
    }
	}
};
</script>

试一下效果:

android点赞功能实现 app点赞功能怎么实现_前端_08


效果还算不错,确实有点开始与目标效果相近了~

4.4 稍微优化一下

略微想一下,立刻发现 可优化的点有三处

  • 第一处:创建的DOM没有销毁,也就是执行完动画的DOM并没有被销毁,这会导致页面上的DOM随着点击的次数变多而线性的增加,非常不好,影响性能
  • 第二处:动画太少,我们可以看到app上的点赞效果是非常丰富的,有向左,有向右,有直线,也有弧线,因此这里还得 增加动画的数量使其变得更加美观一点
  • 第三处:得加一个防抖,减少真的有人或者物理进行疯狂点击,一秒触发N次的那种;

第一点优化
第一处优化就是对于执行完的动画需要及时的销毁,怎么实现呢?其实很简单,我们是用push的方法将配置参数添加进数组的,然后v-for指令自动生成渲染了DOM,那么执行完了之后直接将这个配置删除就完了,由于配置删除,v-for指令自然而言就会将对应的DOM

new Promise(reslove => {
  const params = this.getLikeParams();
  this.likesData.push(params);

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

通过Promise确保代码是同步执行的,执行完动画后直接使用 shift() 函数删除第一个配置项即可,至于为什么要用Promise,那是因为其实有可能有一组动画类名,那么通过Promise我们可以精准的控制添加类名的时机,算是方便扩展吧;
第二处优化
动态太少,那就加动画嘛,多定义几个动画,然后在随机生成class类名的时候把类名带上:

getLikeParams() {
  const classList = ['icon-animate-1', 'icon-animate-2', 'icon-animate-3', 'icon-animate-4', 'icon-animate-5'];
  const colorList = ['#fc5531', '#fcd030', '#00ff7f'];

  const className = classList[this.randomNum(0, classList.length)];
  const colorName = colorList[this.randomNum(0, colorList.length)];

  return {
    animate: className,
    color: colorName,
    name: 'heart-fill',
    id: `${new Date().getTime()}-likes`
  };
},

具体类名对应的动画这里就不放了,直接去代码里看即可,增加了类名动画后,再来看一下效果

android点赞功能实现 app点赞功能怎么实现_前端_09


看上去还不错,但还不够多,表现力还可以更强,但这一篇这里就算了,有兴趣的小伙伴可以自己加一下~

第三处优化

第三处优化主要是没有做防抖处理,那么防抖我们可以直接借助于 lodash中的 throttle函数,用法也非常简单,只需要包裹我们的函数即可:

<script>
import _ from 'lodash';
export default {
	methods: {
		createLikes: _.throttle(function() {
			new Promise(reslove => {
				const params = this.getLikeParams();
				this.likesData.push(params);

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

通过设置后,在50毫秒内只能触发一次函数,这样就防止了那种疯狂触发的情况

五. 小结

本文主要分享了一下 通过CSS3的animation属性,实现了一个疯狂点赞的效果,可能有小伙伴问这种用法会有性能上的问题么,我个人感觉吧,由于动画是CSS3实现的其实性能上没有多大影响,但要说这种做法是最合适嘛,那肯定不是,至少canvas实现的效果肯定比CSS3来的好~
下一篇,我们封装一下,毕竟真实项目中我们不可能不考虑复用以及实现的问题,然后动画也不够完美,下一步继续优化~