Vue组件封装之数字滚动组件
数字滚动组件:包含千分位
index.vue
<template>
<div class="num" :style="'font-size:'+size+'px;'">
<span v-if="minus">-</span>
<number-son v-for="(p, i) in intArr" :key="i" :num="p" :time="time" />
<span v-if="fixed > 0">.</span>
<number-son v-for="(p, i) in floatArr" :key="i" :num="p" :time="time" />
</div>
</template>
<script lang="ts">
import { defineComponent, ref, watch, toRefs } from "vue";
import NumberSon from "./NumberSon.vue";
export default defineComponent({
name: "Number",
components: {
NumberSon,
},
props: {
num: {
type: [Number, String],
default: 0,
}, //数值
size: {
type: Number,
default: 28,
}, //大小
fixed: {
type: Number,
default: 0,
}, //保留小数位,默认0
thousands: {
type: Boolean,
default: false,
}, //是否添加千分位符,默认false
time: {
type: Number,
default: 400,
}, //翻转时间,默认400
},
setup(props) {
const { num } = toRefs(props);
let fixed: number = Number(props.fixed) || 0;
let thousands: boolean = Boolean(props.thousands) || false;
let time: any = Number(props.time) > 0 ? ref(Number(props.time)) : 400;
let arr: any = [];
let floatArr: any = ref([]);
let intArr: any = ref([]);
let minus: any = ref(false);
// 数据处理
let dispose = (data: any) => {
if (data < 0) {
minus = true;
data = -data;
}
let datas: any = String(data);
// 分离整数、小数
if (datas.indexOf(".") != -1) {
arr = datas.split(".");
floatArr.value = arr[1].split(""); //[string]
} else {
arr[0] = datas;
arr[1] = "";
}
intArr.value = arr[0].split(""); // [string]
if (thousands == true && intArr.value.length > 3) {
// 整数——添加千分位
let k = 0;
let b = [];
for (let i = 0; i < intArr.value.length; i++) {
// 类型转换
b[k] = Number(intArr.value[i]);
k++;
if (
i < intArr.value.length - 1 &&
(intArr.value.length - i - 1) % 3 == 0
) {
b[k] = ",";
k++;
}
}
intArr.value = b;
} else {
for (let i = 0; i < intArr.value.length; i++) {
intArr.value[i] = Number(intArr.value[i]);
}
}
// 保留小数位数
let a = [];
for (let i = 0; i < fixed; i++) {
if (floatArr.value[i]) {
a[i] = Number(floatArr.value[i]);
} else {
a[i] = 0;
}
}
floatArr.value = a;
};
// 初始化
dispose(num.value);
// 监听
watch(
num,
(newVal, oldVal) => {
arr = [];
floatArr.value = [];
intArr.value = [];
minus = false;
dispose(newVal);
},
{ deep: true }
);
return { minus, intArr, floatArr, fixed, time };
},
});
</script>
<style scoped>
.num {
/* font-size: 28px; */
}
</style>
滚动组件number-scroll:
<template>
{{ data }}
</template>
<script lang="ts">
import { defineComponent, ref, watch, toRefs, onMounted, onUnmounted } from "vue";
export default defineComponent({
name: "Number",
props: {
num: [Number, String],
time: Number,
},
setup(props) {
const { num } = toRefs(props);
const time: any = ref(props.time);
let data: any = ref(0);
let animation:any;
let transition = (num: any) => {
// 判断是数字、逗号
if (typeof num == "number") {
let lastTime = 0;
const val = time.value / num;
function transitionInt(time: number) {
let interval = time - lastTime;
if (interval > val) {
lastTime = time;
// 整数
if (num == 0) {
data.value = data.value;
} else {
data.value += 1;
}
}
if (data.value < num) {
// 形成回调
window.requestAnimationFrame(transitionInt);
}
}
// 启动动画
animation=window.requestAnimationFrame(transitionInt);
// 当浏览器切换到后台后,requestAnimationFrame是不会再去执行事件了
} else {
data.value = num;
}
};
onMounted(() => {
transition(num.value);
});
onUnmounted(()=>{
window.cancelAnimationFrame(animation)
})
watch(
num,
(newVal, oldVal) => {
data.value=0;
transition(newVal);
},
{ deep: true }
);
return { data };
},
});
</script>
<style scoped>
.son {
display: inline-block;
}
</style>

浙公网安备 33010602011771号