该组件包含正整数及浮点型小数
父组件引用
<roll-number :font-size="16" :num="num"></roll-number>
<script>
setInterval(() => {
this.num = Math.random() * (10000 + 1);
}, 3000);
</script>
rollNumber.vue 数字滚动组件
html
<template>
<div class="container" :style="parentStyle">
<span
v-for="(item, index) in numAry"
:key="index"
class="container-number-roll"
:data-content="getBeforeContent(item).content"
:style="styles[index]"
ref="num"
>0</span
>
</div>
</template>
js
<script>
export default {
name: "rollNumber",
props: {
fontSize: {
type: Number,
default: 18
},
color: {
type: String,
default: "#333"
},
num: {
type: [Number, String],
default: 0
}
},
data() {
return {
styles: {}
};
},
watch: {
num() {
this.numChange();
},
color() {
this.extraStyles({
"--color": this.color
});
}
},
computed: {
numAry() {
return this.num.toString().split("");
},
parentStyle() {
return {
fontSize: this.fontSize + "px",
height: this.fontSize + "px"
};
}
},
mounted() {
this.numChange();
this.color != "#333" &&
this.extraStyles({
"--color": this.color
});
},
methods: {
getBeforeContent(item) {
let res = isNaN(parseInt(item)) ? "." : "0123456789";
return {
isNaN: isNaN(parseInt(item)),
content: res
};
},
extraStyles(obj = {}) {
this.numAry.map((item, index) => {
Object.assign(this.styles[index], obj);
});
this.$forceUpdate();
},
setStyles(obj = {}) {
let defaultStyle = {
fontSize: this.fontSize + "px",
height: this.fontSize + "px",
width: 0.7 * this.fontSize + "px"
};
Object.assign(defaultStyle, obj);
return defaultStyle;
},
numChange() {
this.numAry.map((item, index) => {
let top = 0,
style = {};
if (this.getBeforeContent(item).isNaN) {
top = this.fontSize * 0.2;
style.width = 0.2 * this.fontSize + "px";
} else {
top = -parseInt(item) * this.fontSize;
}
Object.assign(style, {
"--local": `translate(0, ${top}px)`
});
this.styles[index] = this.setStyles(style);
});
this.$forceUpdate();
}
}
};
</script>
css
<style lang="scss" scoped>
.container {
overflow: hidden !important;
}
.container-number-roll {
--local: translate(0, -0px);
--color: #333;
position: relative;
/* 文字竖显示 */
writing-mode: vertical-rl;
text-orientation: upright;
color: rgba(255, 255, 255, 0);
&::before {
width: 100%;
content: attr(data-content);
position: absolute;
color: var(--color);
font-weight: bold;
/* 文字竖显示 */
writing-mode: vertical-rl;
text-orientation: upright;
// animation: loca1 1s ease-in-out forwards;
transform: var(--local);
transition: transform 1s ease-in-out;
display: flex;
justify-content: center;
align-items: center;
}
}
</style>