vue 自定义动态数字组件

该文章介绍了一个名为DynamicNumbers的Vue组件,用于创建动态滚动的数字效果。组件使用requestAnimationFrame实现平滑动画,支持数值格式化,当数字超过一万时自动以万为单位显示。同时,文章中还包含了一个辅助方法floattotwo,用于将数字转换为指定小数位数的字符串。
摘要由CSDN通过智能技术生成

1.创建组件 DynamicNumbers.vue

<template>
  <div class="statistics-num">
    <el-tooltip
      :content="content"
      placement="top"
      effect="light"
      :disabled="+to < 10000"
      class="tooltip"
    >
      <div v-if="to">
        <span class="num">{{ currentNumber.toLocaleString() }}</span>
        <span class="num-isHtml" v-show="getTenThousand">{{
          isHtml || ""
        }}</span>
        <span class="num-unit">{{ unit || "" }}</span>
      </div>
      <div v-else>-</div>
    </el-tooltip>
  </div>
</template>

<script>
import { floattotwo } from "@/utils";
export default {
  name: "DynamicNumbers",
  props: {
    // 目标数字
    to: {
      type: [String, Number],
      default: () => 0
    },
    // 动画持续时间(单位:毫秒)
    duration: {
      type: [String, Number],
      default: () => 2000
    },
    // // 当前数字,初始值为0
    currentVal: {
      type: [String, Number],
      default: () => 0
    },
    //  动画开始时间
    startTime: {
      type: [String, Number],
      default: () => null
    },
    unit: {
      type: [String, Number],
      default: () => ""
    },
    getTenThousand: {
      type: [String, Number, Boolean],
      default: () => 10000
    }
  },
  data() {
    return {
      // 目标数字
      endVal: 0,
      // 动画持续时间(单位:毫秒)
      durations: 2000,
      // 当前数字,初始值为0
      currentNumber: 0,
      // 动画开始时间
      animationStartTime: null,
      // 过万时,以万为单位展示
      isHtml: "",
      tenThousand: 10000
    };
  },
  computed: {
    content() {
      return this.to + " " + this.unit;
    }
  },
  watch: {
    to(val) {
      this.endVal = val;
    },
    duration(val) {
      this.durations = val;
    },
    currentVal(val) {
      this.currentNumber = val;
    },
    startTime(val) {
      this.animationStartTime = val;
    },
    getTenThousand: {
      deep: true,
      handler(val) {
        this.tenThousand = val;
        console.log(val);
      },
      immediate: true
    }
  },
  mounted() {
    // 在组件挂载后启动数字滚动效果
    this.startCount();
  },
  methods: {
    startCount() {
      // 使用requestAnimationFrame()方法实现动画效果
      window.requestAnimationFrame(timestamp => {
        // 如果animationStartTime属性为空,则将当前时间赋值给它
        if (!this.animationStartTime) this.animationStartTime = timestamp;
        // 计算当前时间与动画开始时间之间的时间差,以及时间差所占总时间的百分比
        const progress = timestamp - this.animationStartTime;
        const percentage = Math.min(progress / this.durations, 1);
        // 根据时间百分比计算当前数字,并将其赋值给currentNumber属性
        this.currentNumber = Math.floor(percentage * (this.endVal - 0) + 0);
        // 如果动画持续时间还没有达到,则继续循环调用startCount()方法
        if (progress < this.durations) {
          this.startCount();
        }
        if (+this.currentNumber >= this.tenThousand) {
          let deal_num = parseFloat(+this.currentNumber);
          this.isHtml = "万";
          this.currentNumber =
            deal_num >= this.tenThousand
              ? floattotwo(2, deal_num / this.tenThousand)
              : deal_num;
        }
      });
    }
  }
};
</script>

<style></style>

2.页面中使用

<dynamic-numbers
  :to="item.num"
  :duration="2000"
  :unit="item.unit"
  class="number" 
>
</dynamic-numbers>

3.@/utils 方法

/**
 * Parse the time to string
 * type is 小数点后几位
 * msg为待浮点数或字符串,并为最后返回值
 */
export function floattotwo(type, msg) {
  var f = parseFloat(msg);
  if (isNaN(f)) {
    return "false";
  }
  switch (type) {

    case 0: //整型
      var s = parseInt(f);
      return s;
      // msg = parseFloat(msg);
      // return Math.floor(msg * 10) / 10;
      break;
    case 1: //小数点后一位

      var f = Math.round(msg * 10) / 10;
      var s = f.toString();
      var rs = s.indexOf('.');
      if (rs < 0) {
        rs = s.length;
        s += '.';
      }
      while (s.length <= rs + 1) {
        s += '0';
      }
      return s;
      // msg = parseFloat(msg);
      // return Math.floor(msg * 10) / 10;
      break;
    case 2:
      //制保留2位小数,如:2,会在2后面补上00.即2.00
      var f = Math.round(msg * 100) / 100;
      var s = f.toString();
      var rs = s.indexOf('.');
      if (rs < 0) {
        rs = s.length;
        s += '.';
      }
      while (s.length <= rs + 2) {
        s += '0';
      }
      //msg = parseFloat(msg);
      return s;
      break;
    case 99: //保存原数据,不截取
      return msg;
      break;
    default:
      alert("数据类型有误");
      return;
  }
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值