vue3封裝數(shù)字滾動(dòng)組件的實(shí)現(xiàn)示例
效果展示:

代碼:
<template>
<div class="counter-container">
<div v-for="(item, index) in numArr" :key="index" :class="item === ',' || item === '.' ? 'mark-item' : 'num-item'">
<span class="pointer" v-if="item == ',' || item == '.'">{{ item }}</span>
<span ref="numberItem" v-else class="num">
{{ flipNum }}
</span>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, watch, nextTick, onMounted } from "vue";
const props = defineProps({
num: {
type: Number,
default: 0
},
duration: {
type: Number,
default: 1
}
});
let numArr = ref(["0", "0", ",", "0", "0", "0", ",", "0", "0", "0"]);
const flipNum = "0123456789";
// let timer = null;
const numberItem = ref<Array<HTMLSpanElement> | null>(null);
// 處理傳遞過(guò)來(lái)的數(shù)字,轉(zhuǎn)化為數(shù)組
function numToArr() {
const str = props.num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
numArr.value = str.split("");
}
function rollNum() {
const numItems = numberItem.value;
const numberArr = numArr.value.filter(item => item !== "," && item !== ".");
numberArr.forEach((item, index) => {
const num = parseInt(item);
if (numItems) {
const numItem = numItems[index];
numItem.style.transform = `translate(-50%, -${num * 10}%)`;
}
});
}
// 監(jiān)聽(tīng)數(shù)字變化,更新數(shù)字
const initNumber = () => {
numToArr();
nextTick(() => {
setTimeout(() => {
rollNum();
}, props.duration * 1000);
});
};
watch(
() => props.num,
() => {
initNumber();
}
);
onMounted(() => {
initNumber();
});
</script>
<style lang="scss" scoped>
.counter-container {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
.counter-container .num-item {
position: relative;
box-sizing: border-box;
width: 22px;
height: 34px;
padding: 8px;
margin-left: 4px;
overflow: hidden;
font-size: 20px;
font-weight: bold;
color: #ffffff;
text-align: center;
background-image: url("@/assets/images/dataBoard/num_wrap.png");
background-repeat: no-repeat;
background-size: 100% 100%;
}
.counter-container .mark-item {
height: 34px;
margin-left: 4px;
font-size: 24px;
font-weight: 800;
line-height: 38px;
color: #ffffff;
text-align: center;
}
.counter-container .num {
position: absolute;
top: 6px;
left: 50%;
letter-spacing: 8px;
writing-mode: vertical-lr;
transition: all 1s ease-in-out;
transform: translate(-50%, 0);
text-orientation: upright;
}
</style>到此這篇關(guān)于vue3封裝數(shù)字滾動(dòng)組件的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)vue3 數(shù)字滾動(dòng)組件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于VUE點(diǎn)擊父組件按鈕跳轉(zhuǎn)到子組件的問(wèn)題及解決方案
本文主要介紹了在Vue框架中,如何通過(guò)父組件的點(diǎn)擊事件打開(kāi)子組件中的彈窗并展示表格內(nèi)容,主要步驟包括在父組件中定義數(shù)據(jù)屬性,創(chuàng)建并定義子組件的彈窗和表格內(nèi)容,通過(guò)props屬性和自定義事件實(shí)現(xiàn)父子組件間的數(shù)據(jù)傳遞和方法調(diào)用2024-10-10
Element樹(shù)形控件整合帶圖標(biāo)的下拉菜單(tree+dropdown+input)
Element UI 官網(wǎng)提供的樹(shù)形控件包含基礎(chǔ)的、可選擇的、自定義節(jié)點(diǎn)內(nèi)容的、帶節(jié)點(diǎn)過(guò)濾的以及可拖拽節(jié)點(diǎn)的樹(shù)形結(jié)構(gòu),本文實(shí)現(xiàn)了樹(shù)形控件整合帶圖標(biāo)的下拉菜單,感興趣的可以了解一下2021-07-07
vue3中實(shí)現(xiàn)組件通信的方法總結(jié)
在Vue3中,有多種方法可以實(shí)現(xiàn)組件之間的通信,本文就通過(guò)代碼示例給大家總結(jié)一些vue3實(shí)現(xiàn)組件通信的常用方法,需要的朋友可以參考下2023-06-06
ElementUI+命名視圖實(shí)現(xiàn)復(fù)雜頂部和左側(cè)導(dǎo)航欄
本文主要介紹了ElementUI+命名視圖實(shí)現(xiàn)復(fù)雜頂部和左側(cè)導(dǎo)航欄,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04
Vue2.0+ElementUI+PageHelper實(shí)現(xiàn)的表格分頁(yè)功能
ElementUI也是一套很不錯(cuò)的組件庫(kù),對(duì)于我們經(jīng)常用到的表格、表單、時(shí)間日期選擇器等常用組件都有著很好的封裝和接口。這篇文章主要介紹了Vue2.0+ElementUI+PageHelper實(shí)現(xiàn)的表格分頁(yè),需要的朋友可以參考下2021-10-10
Vue.js每天必學(xué)之指令系統(tǒng)與自定義指令
Vue.js每天必學(xué)之指令系統(tǒng)與自定義指令,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09
Vue父組件和子組件之間數(shù)據(jù)傳遞和方法調(diào)用
vue組件在通信中,無(wú)論是子組件向父組件傳值還是父組件向子組件傳值,他們都有一個(gè)共同點(diǎn)就是有中間介質(zhì),子向父的介質(zhì)是自定義事件,父向子的介質(zhì)是props中的屬性。2022-12-12

