<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",
}