先看效果:
<div>
<scroll-number ref="snRef"/>
</div>
// 引入组件
// 我这里是放在components里面,放什么位置你们自己定义
import ScrollNumber from '@/components/ScrollNumber/index'
onMounted(() => {
proxy.$refs.snRef.start(82922);
})
ScrollNumber组件:
<template>
<div class="box">
<div :class="{'number-item': !isNaN(item), 'number-char': !!isNaN(item) }"
v-for="(item,index) in computeNumber" :key="index">
<span v-if="!isNaN(item)">
<i ref="numberItemRef">0123456789</i>
</span>
<div class="number-char" v-else>{{item}}</div>
</div>
</div>
</template>
<script setup>
const {proxy} = getCurrentInstance();
const props = defineProps({
number: {
type: Number,
default: 0
}
})
const computeNumber = ref([]);
const newNumber = ref(0);
// 千分位
const formatNumber = (num) => {
return (num + '').replace(/(\d{1,3})(?=(\d{3})+(?:$|\.))/g,'$1,')
}
// 开始滚动
const start = (num) => {
newNumber.value = num
computeNumber.value = (formatNumber(newNumber.value)).split('')
setNumberTransform()
}
// 设置每一位数字的偏移
const setNumberTransform = () => {
nextTick(() => {
let numberItems = proxy.$refs.numberItemRef
let numberArr = computeNumber.value.filter(item => !isNaN(item))
for (let index = 0; index < numberItems.length; index++) {
let elem = numberItems[index]
elem.style.transform = `translate(-50%, -${numberArr[index] * 10}%)`
}
})
}
defineExpose({ // vue3中子组件要暴露一下,否则父组件有可能找不到
start
})
</script>
<style lang="scss" scoped>
.box {
display: flex;
height: 38.5px;
.number-char {
color: #fff;
display: table-cell;
vertical-align: bottom;
}
}
.number-item {
width: 18px;
color: #fff;
overflow: hidden;
background-size:100% 100%;
& > span {
position: relative;
display: inline-block;
width: 100%;
height: 100%;
writing-mode: vertical-rl;
text-orientation: upright;
overflow: hidden;
& > i {
position: absolute;
top: 0;
left: 45%;
transform: translate(-50%,0);
transition: transform 1s ease-in-out;
font-style: unset;
}
}
}
</style>