美文网首页让前端飞Web前端之路
金额动画组件 - vue+typescript

金额动画组件 - vue+typescript

作者: 蓝海00 | 来源:发表于2020-08-10 16:51 被阅读0次
  • 图例


  • 组件代码参考
<template>
  <div class="numberCounter">
    <h2 :data-to="to" :data-from="from" data-speed="1000" ref="countNumber"></h2>
  </div>
</template>

<script lang="ts">
import { Component, Vue, Prop, Watch } from "vue-property-decorator";

@Component
export default class NumberCounter extends Vue {
  @Prop({
    type: Number,
    default: 0,
  })
  to!: number;
  @Watch("to")
  watchTo(val: number) {
    $(this.$refs["countNumber"]).attr(
      "data-from",
      $(this.$refs["countNumber"]).data("to")
    );
    $(this.$refs["countNumber"]).attr("data-to", val);
    this.initialize();
    this.start();
  }
  @Prop({
    type: Number,
    default: 0,
  })
  from!: number;

  mounted() {
    this.initialize();
    this.start();
  }
  initialize() {
    ($.fn as any).countTo = function (options: any) {
      options = options || {};
      return $(this).each(function () {
        // 设置当前元素的选项
        let settings = $.extend(
          {},
          ($.fn as any).countTo.defaults,
          {
            from: +this.dataset.from ? +this.dataset.from : 0,
            to: +this.dataset.to ? +this.dataset.to : 0,
            speed: $(this).data("speed"),
            refreshInterval: $(this).data("refresh-interval"),
            decimals: $(this).data("decimals"),
          },
          options
        );

        // 多次更新该值,以及每次更新时该值增加多少
        let loops = Math.ceil(settings.speed / settings.refreshInterval),
          increment = (settings.to - settings.from) / loops;

        // 每次更新都会改变的引用和变量
        let self = this,
          $self = $(this),
          loopCount = 0,
          value = settings.from,
          data = $self.data("countTo") || {};

        $self.data("countTo", data);

        // 如果可以找到现有的计时器,首先清除它
        if (data.interval) {
          clearInterval(data.interval);
        }
        data.interval = setInterval(updateTimer, settings.refreshInterval);

        // 用初始值初始化元素
        render(value);

        function updateTimer() {
          value += increment;
          loopCount++;

          render(value);

          if (typeof settings.onUpdate == "function") {
            settings.onUpdate.call(self, value);
          }

          if (loopCount >= loops) {
            // 删除间隔
            $self.removeData("countTo");
            clearInterval(data.interval);
            value = settings.to;

            if (typeof settings.onComplete == "function") {
              settings.onComplete.call(self, value);
            }
          }
        }

        function render(value: any) {
          let formattedValue = settings.formatter.call(self, value, settings);
          formattedValue = formattedValue === "-0.00" ? "0.00" : formattedValue;
          $self.html(formattedValue);
        }
      });
    };

    // 初始化默认值
    ($.fn as any).countTo.defaults = {
      from: 0, // 元素的起始数字
      to: 0, // 元素结束的数字
      speed: 1000, // 需要多长时间来计算目标数字
      refreshInterval: 100, // 元素应该多久更新一次
      decimals: 2, // 要表示的小数位数
      formatter: formatter, // 处理程序,用于在呈现之前格式化值
      onUpdate: null, // 每次更新元素时的回调方法
      onComplete: null, // 元素完成更新时的回调方法
    };

    function formatter(value: any, settings: any) {
      return value.toFixed(settings.decimals);
    }

    // 自定义格式示例
    $(this.$refs.countNumber).data("countToOptions", {
      formatter: function (value: any, options: any) {
        return value
          .toFixed(options.decimals)
          .replace(/\B(?=(?:\d{3})+(?!\d))/g, ",");
      },
    });
  }
  start() {
    // 启动所有计时器
    $(this.$refs.countNumber).each(count);

    function count(this: any, options: any) {
      let $this: any = $(this);
      options = $.extend({}, options || {}, $this.data("countToOptions") || {});
      $this.countTo(options);
    }
  }
}
</script>

<style scoped lang="scss">
.numberCounter {
}
</style>
  • 使用
<div class="orderBoxInner" @click="lendingQuotas.number=100901">
  <number-counter :to="lendingQuotas.number" />
  <h3 class="orderDocs">放款额度(元)</h3>
</div>

相关文章

网友评论

    本文标题:金额动画组件 - vue+typescript

    本文链接:https://www.haomeiwen.com/subject/zhmjdktx.html