vue项目 数字自动增加 并转化成带有分号的数字

这是一个关于Vue组件`CountTo`的实现,用于创建数字从`startVal`过渡到`endVal`的动画效果。组件支持自定义开始值、结束值、动画时长、小数位数、前缀、后缀、分隔符和小数点等属性。同时,它还提供了颜色、缓动效果、动画类型等高级特性,并监听数值变化以触发相关事件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<template>
  <div class="headers">
  <CountTo
   :startVal="0"
   :endVal="传入数字"
  />
  </div>
</template>

<script>
import CountTo from "@/components/CountTo/CountTo.vue";
components: {
  CountTo,
}

</script>

src/components/CountTo/CountTo.vue

<template>
  <!-- 父组件使用 <CountTo :startVal="0" :endVal="传入数字" class="text-2xl" /> -->
  <div>
    <span :style="{ color }"> {{ value }} \\ {{ outputValue }} </span>
  </div>
</template>

<script>
import { useTransition, TransitionPresets } from "@vueuse/core";
import { isNumber } from "@/utils/is";
// import { debug } from "console";
export default {
  props: {
    startVal: { type: Number, default: 0 },
    endVal: { type: Number, default: 0 },
    duration: { type: Number, default: 50000 },
    autoplay: { type: Boolean, default: true },
    decimals: {
      type: Number,
      default: 2,
    },
    prefix: { type: String, default: "" },
    suffix: { type: String, default: "" },
    separator: { type: String, default: "," },
    decimal: { type: String, default: "." },
    /**
     * font color
     */
    color: { type: String },
    /**
     * Turn on digital animation
     */
    useEasing: { type: Boolean, default: true },
    /**
     * Digital animation
     */
    transition: { type: String, default: "linear" },
  },

  data() {
    return {
      disabled: false,
      source: this.startVal,
      str: 1236,
      outputValue: 0,
    };
  },

  computed: {
    getVal() {
      const { endVal, startVal } = this;
      return {
        startVal,
        endVal,
      };
    },
    value() {
      let n = useTransition(this.source).value;
      n = useTransition(source, {
        disabled,
        duration: duration,
        onFinished: () => {
          return this.$emit("onFinished");
        },
        onStarted: () => {
          return this.$emit("onStarted");
        },
        ...(useEasing ? { transition: TransitionPresets[transition].name } : {}),
      }).value;
      let num = this.formatNumber(n);

      return num;
    },
  },
  watch: {
    getVal: {
      deep: true,
      immediate: true,
      handler(newVal, oldVal) {
        console.log(newVal);
        if (this.autoplay) {
          this.start();
        }
      },
    },
    // "endVal,startVal": {
    //   deep: true,
    //   immediate: true,
    //   handler(newVal, oldVal) {
    //     console.log(newVal);
    //     ;
    //     if (this.autoplay) {
    //       this.start();
    //     }
    //   },
    // },
    startVal: {
      deep: true,
      immediate: true,
      handler(newVal, oldVal) {
        this.source = newVal;
      },
    },
  },

  mounted() {
    this.autoplay && this.start();
  },

  methods: {
    start() {
      this.run();
      this.source = this.endVal;
    },

    run() {
      let { source, disabled, duration, useEasing, transition } = this;
      let str1 = TransitionPresets[transition];
      console.log(str1, useEasing);
      this.outputValue = useTransition(source, {
        disabled,
        duration: duration,
        onFinished: () => {
          return this.$emit("onFinished");
        },
        onStarted: () => {
          return this.$emit("onStarted");
        },
        ...(useEasing ? { transition: TransitionPresets[transition].name } : {}),
      }).value;
    },

    // 添加百分号 如果仅仅想给数字加百分号 使用这个就行了
    formatNumber(num) {
      if (!num && num !== 0) {
        return "";
      }
// decimal 小数点   .
// decimals 几位小数  .xxx
// separator 分号 ,
      const { decimals, decimal, separator, suffix, prefix } = this;
      num = Number(num).toFixed(decimals);
      num += "";

      const x = num.split(".");
      let x1 = x[0];
      const x2 = x.length > 1 ? decimal + x[1] : "";

      const rgx = /(\d+)(\d{3})/;
      if (separator && !isNumber(separator)) {
        while (rgx.test(x1)) {
          x1 = x1.replace(rgx, "$1" + separator + "$2");
        }
      }
      let m = prefix + x1 + x2 + suffix;
      return m;
    },
  },
};
</script>

<style lang="scss" scoped></style>


src/utils/is.js

const toString = Object.prototype.toString;

export function is(val, type) {
	return toString.call(val) === `[object ${type}]`;
}

export function isDef(val) {
	return typeof val !== "undefined";
}

export function isUnDef(val) {
	return !isDef(val);
}

export function isObject(val) {
	return val !== null && is(val, "Object");
}

export function isEmpty(val) {
	if (isArray(val) || isString(val)) {
		return val.length === 0;
	}

	if (val instanceof Map || val instanceof Set) {
		return val.size === 0;
	}

	if (isObject(val)) {
		return Object.keys(val).length === 0;
	}

	return false;
}

export function isDate(val) {
	return is(val, "Date");
}

export function isNull(val) {
	return val === null;
}

export function isNullAndUnDef(val) {
	return isUnDef(val) && isNull(val);
}

export function isNullOrUnDef(val) {
	return isUnDef(val) || isNull(val);
}

export function isNumber(val) {
	return is(val, "Number");
}

export function isPromise(val) {
	return (
		is(val, "Promise") &&
		isObject(val) &&
		isFunction(val.then) &&
		isFunction(val.catch)
	);
}

export function isString(val) {
	return is(val, "String");
}

export function isFunction(val) {
	return typeof val === "function";
}

export function isBoolean(val) {
	return is(val, "Boolean");
}

export function isRegExp(val) {
	return is(val, "RegExp");
}

export function isArray(val) {
	return val && Array.isArray(val);
}

export function isWindow(val) {
	return typeof window !== "undefined" && is(val, "Window");
}

export function isElement(val) {
	return isObject(val) && !!val.tagName;
}

export function isMap(val) {
	return is(val, "Map");
}

export const isServer = typeof window === "undefined";

export const isClient = !isServer;

export function isUrl(path) {
	const reg =
		/(((^https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/;
	return reg.test(path);
}

package.json

  "dependencies": {
    "@vue/composition-api": "^1.4.9",
    "@vueuse/core": "^8.2.6",
   }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端酱紫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值