vue中优雅实现数字递增特效的详细过程

 更新时间:2022年12月14日 10:42:54   作者:拾荒草  
项目中需要做数字滚动增加的效果,一开始很懵,研究了一下原理,发现很简单,下面这篇文章主要给大家介绍了关于vue中优雅实现数字递增特效的详细过程,需要的朋友可以参考下

需求

前几天项目开发中遇到一个需求,需要在数字更新时,实现其动态递增的效果

并且,在数字大于10000时,将单位进行转换,如数字大于10000时,单位从变为万

我们以vue中开发为例,一一实现下这两个需求。

实现

基本开发思路

实现数字递增,最容易的,我们应该可以想到通过setinterval函数实现数字累加功能。比如,我们的最终值是finanllyNum, 我们可以很快想到这样的函数:

let finalNum = 1200
let count = 0
let timer = setInterval(() => {
  count ++ 
  if(count > finalNum){
    // 避免count大于finalNum最终数字显示不对
    count = finalNum
    // 清空定时器
    clearInterval(timer)
    timer = null
  }
}, 10);

这个代码中,count是我们要实时在浏览器中显示的数字。我们每10ms实现数字进行一次递增,从而实现数字的动态递增特效。

指令的开发

由于项目中涉及很多这样的功能点,因此,这个功能应该被统一进行封装和复用。由于我们使用的是vue技术栈,显然,通过vue中的指令来实现这个功能最合适。

以下实现方案基于vue指令实现,因此,您需要参考官网了解学习vue中指令的基本用法。

vue2和vue3指令的用法大同小异,本示例以vue2进行演示

指令的基本结构

首先,我们创建change.js文件,写入指令的最基本结构

// js实现动态变化的数字
const directive = {
  inserted(el:any, binding:any) {
    ...
  },
};
export default directive

main.js中引入该文件

import Vue from "vue";
import App from "./App.vue";
import directive from "./change";

Vue.config.productionTip = false;
// 注册名为 change 的指令
Vue.directive("change", directive);
new Vue({
  render: (h) => h(App),
}).$mount("#app");

此时,我们创造了一个名为v-change的指令,我们直接使用

// App.vue
<template>
  <div id="app">
    <span> 240 </span>
  </div>
</template>

结合我们最开始的实现思路,可以完善指令

// js实现动态变化的数字
const directive = {
  inserted(el, binding) {
  	// 获取到需要动态变化的数值
    let finalNum = el.innerText;
    let count = 0;
    let timer = setInterval(() => {
      count++;
      el.innerText = count;
      if (count > finalNum) {
        //  避免count大于finalNum最终数字显示不对
        count = finalNum;
        el.innerText = count;
        // 清空定时器
        clearInterval(timer);
        timer = null;
      }
    }, 10);
  },
};
export default directive;

打开浏览器,可以看到我们的指令基本完成了。

但目前这个指令有个非常大的问题。我们设置的是每10ms增加一下数字(数字加1),如果数字非常大比如为12000,那么这个数字的动态变化过程岂不是非常长?

我们应该让数字无论多大,都在指定时间完成才行。

指令的优化

要想数字在指定时间完成变化,我们需要找到这个变化过程中的一些数学关系。目前,我们已经知道的有变化初始值0,变化最终值12000,动画总时长(假设为2S)。其次,每帧动画的间隔时长也是我们应该考虑的一个数值。

一开始的示例中,每10ms就是每帧动画的间隔时长。

简单理解,动画的间隔时长就是每秒动画变化的频率

我们通过两个图来理解一下:

如图,时间间隔为 166.7ms时,数字1s变化6次,分别为 100,200,300,400,500,600

当时间间隔为 100ms时,数字1s变化10次,以此为60,120,180,.......,600

可见,时间间隔越小,数字变化的也就越快。

现在我们可以得到这样一个数学关系:

动画总时长 / 时间间隔 * 数字的步长(每 1时间间隔增加的值) = 1200

现在,我们可以优化一下指令了

// js实现动态变化的数字
const directive = {
  inserted(el, binding) {
    // 最终要显示的数字
    let finalNum = el.innerText;
    // 动画间隔
    let rate = 30;
    // 总时长
    let time = 2000;
    // 步长,数据增加间隔
    let step = finalNum / (time / rate);
    // 初始值
    let count = 0;
    // 要保留的小数
    let timer = setInterval(() => {
      count = count + step;
      el.innerText = count.toFixed(0);
      if (count > finalNum) {
        //  避免count大于finalNum最终数字显示不对
        count = finalNum;
        el.innerText = count;
        // 清空定时器
        clearInterval(timer);
        timer = null;
      }
    }, rate);
  },
};
export default directive;

效果非常不错!

实现单位变化

如何数字后面有单位,我们要怎么实现单位的变化呢?

第一种方法:

通过js动态为数字后赋值,这种方法很好理解

    let timer = setInterval(() => {
      count = count + step;
      // 根据不同数值显示不同单位
      if( count < 1000 ){
        el.innerText = count.toFixed(0) + "个"
      }else{
        el.innerText = (count / 1000 ).toFixed(0) + "千个"
      }
      if (count > finalNum) {
        count = finalNum;
        //  避免count大于finalNum最终数字显示不对
        if( count < 1000 ){
          el.innerText = count.toFixed(0) + "个"
        }else{
          el.innerText = (count / 1000 ).toFixed(0) + "千个"
        }
        // 清空定时器
        clearInterval(timer);
        timer = null;
      }
    }, rate);

这个方法有一个很大的缺陷,就是单位必须写死在指令里,如下图,如果我们要实现很多动态数字而且需要不同单位该怎么办呢?

第二种方法:

指令是可以传递参数的

<template>
  <div id="app">
    <div >
      <span v-change="{eUnit:'个',eUnit:'万个'}"> 1200 </span>
    </div>
  </div>
</template>

通过binding.value可以接受参数。我们可以通过获取的参数,来处理逻辑,如下:

// js实现动态变化的数字
const directive = {
  inserted(el, binding) {
    // .....
    let timer = setInterval(() => {
      count = count + step;
      if( count < 1000 ){
        // binding.value.bUnit是我们通过指令传递进来的参数
        el.innerText = count.toFixed(0) +  binding.value.bUnit
      }else{
        el.innerText = (count / 1000 ).toFixed(0) + binding.value.eUnit
      }
      if (count > finalNum) {
      //  避免count大于finalNum最终数字显示不对
        count = finalNum;
        if( count < 1000 ){
          el.innerText = count.toFixed(0) + binding.value.bUnit
        }else{
          el.innerText = (count / 1000 ).toFixed(0) + binding.value.eUnit
        }
        // 清空定时器
        clearInterval(timer);
        timer = null;
      }
    }, rate);
  },
};
export default directive;

当然,还有其他实现逻辑,也欢迎大家发挥自己的所长!

总结

到此这篇关于vue中优雅实现数字递增特效的文章就介绍到这了,更多相关vue数字递增特效内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Vue3获取DOM节点的3种方式实例

    Vue3获取DOM节点的3种方式实例

    Vue本来无需操作DOM来更新界面,而且Vue也不推荐我们直接操作DOM,但是我们非要拿到DOM操作DOM怎么办,下面这篇文章主要给大家介绍了关于Vue3获取DOM节点的3种方式,需要的朋友可以参考下
    2023-02-02
  • Vue中通过vue-router实现命名视图的问题

    Vue中通过vue-router实现命名视图的问题

    这篇文章主要介绍了在Vue中通过vue-router实现命名视图,本文给大家提到了vue-router的原理解析,给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-04-04
  • vue+jquery+lodash实现滑动时顶部悬浮固定效果

    vue+jquery+lodash实现滑动时顶部悬浮固定效果

    这篇文章主要为大家详细介绍了vue+jquery+lodash实现滑动时顶部悬浮固定效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-04-04
  • 关于vuejs中v-if和v-show的区别及v-show不起作用问题

    关于vuejs中v-if和v-show的区别及v-show不起作用问题

    v-if 有更高的切换开销,而 v-show 有更高的出事渲染开销.因此,如果需要非常频繁的切换,那么使用v-show好一点;如果在运行时条件不太可能改变,则使用v-if 好点
    2018-03-03
  • vue动态修改页面title的两种方法

    vue动态修改页面title的两种方法

    本文主要介绍了vue动态修改页面title的两种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • Element中table组件按照属性执行合并操作详解

    Element中table组件按照属性执行合并操作详解

    在我们日常开发中,表格业务基本是必不可少的,对于老手来说确实简单,家常便饭罢了,但是对于新手小白如何最快上手搞定需求呢?本文从思路开始着手,帮你快速搞定表格
    2022-11-11
  • vue中$nextTick的用法讲解

    vue中$nextTick的用法讲解

    今天小编就为大家分享一篇关于vue中$nextTick的用法讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • 前端登录退出处理Token问题(获取、缓存、失效处理)及代码实现方法

    前端登录退出处理Token问题(获取、缓存、失效处理)及代码实现方法

    token是一个用户信息的表示,在登录中将会从后端拿到token,然后用户才可以进行往后的一系列操作,这篇文章主要给大家介绍了关于前端登录退出处理Token问题(获取、缓存、失效处理)及代码实现的相关资料,需要的朋友可以参考下
    2024-01-01
  • 用vue构建多页面应用的示例代码

    用vue构建多页面应用的示例代码

    这篇文章主要介绍了用vue构建多页面应用的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • vue-cli 目录结构详细讲解总结

    vue-cli 目录结构详细讲解总结

    这篇文章主要介绍了vue-cli 目录结构详细讲解总结,详细的介绍了整个项目的目录以及目录文件的用法,非常具有实用价值,需要的朋友可以参考下
    2019-01-01

最新评论