先看效果图
具体实现
1.创建一个文件目录queryDemandTotal 里面新增index.tsx 和index.module.scss文件(使用less的自定义)
注意:先看组件主体Dom结构 有一个ref_for Vue3 jsx中想要在循环遍历中设置ref并获取$refs 必须设置ref_fo={true} 否则打印出来的结果不是预期值
其他的直接上代码 逻辑很简单 核心就是一个transform样式控制
index.tsx完整代码如下:
import { defineComponent, onMounted, reactive, ref } from "vue";
import style from "./index.module.scss";
const QueryDemandTotal = defineComponent({
props: {
value: {
type: String,
default() {
return 0;
},
},
time: {
type: Number,
default() {
return 3;
},
},
},
setup(props) {
// 定义一个numberItem变量,用于存储数字
const numberItem = ref();
let orderNum = reactive(["0", "0", "0", "0", "0", "0"]);
let currentNum = Number(props.value) - 1;
onMounted(() => {
// 将当前值转换为订单数量
toOrderNum(currentNum.toString());
// 增长订单数量
increaseNumber(props.time);
});
// 定时增长数字
const increaseNumber = (time: number) => {
setInterval(() => {
currentNum++;
toOrderNum(currentNum.toString());
setNumberTransform();
}, time * 1000);
};
// 设置文字滚动
const setNumberTransform = () => {
const numberItems = numberItem.value;
const numberArr = orderNum.filter((item) => !isNaN(Number(item)));
for (let index = 0; index < numberItems.length; index++) {
const elem = numberItems[index];
elem.style.transform = `translate(-50%, -${
Number(numberArr[index]) * 10
}%)`;
}
};
// 处理传过来的具体值value
const toOrderNum = (num: string) => {
let Num = num.toString();
if (Num.length < 6) {
Num = "0" + Num;
toOrderNum(Num);
} else if (Num.length === 6) {
orderNum = Num.split("");
}
};
return () => (
<div class={style.boxItem}>
{orderNum.map((v, i) => (
<li class={style.numberItem} key={i}>
<span>
<i ref={numberItem} ref_for={true}>
0123456789
</i>
</span>
</li>
))}
<p class={style.nums}>个</p>
</div>
);
},
});
export default QueryDemandTotal;
index.module.scss 完整代码如下
/*具体值value总量滚动数字设置*/
.boxItem {
.nums {
font-size: 24px;
font-weight: 400;
color: #58daff;
}
position: relative;
height: 64px;
font-size: 54px;
line-height: 41px;
text-align: center;
list-style: none;
color: #2d7cff;
writing-mode: vertical-lr;
text-orientation: upright;
/*文字禁止编辑*/
-moz-user-select: none; /*火狐*/
-webkit-user-select: none; /*webkit浏览器*/
-ms-user-select: none; /*IE10*/
-khtml-user-select: none; /*早期浏览器*/
user-select: none;
}
/*滚动数字设置*/
.numberItem {
width: 49px;
height: 64px;
list-style: none;
margin-right: 5px;
border-image: linear-gradient(0deg, #71cafe, #edf8ff, #71cafe) 2 2;
background: url("@/assets/images/numberBg.png") no-repeat;
background-size: 100% 100%;
border-radius: 2px;
& > span {
position: relative;
display: inline-block;
margin-right: 10px;
width: 100%;
height: 90%;
writing-mode: vertical-rl;
text-orientation: upright;
overflow: hidden;
& > i {
font-family: "DS-Digital-BoldItalic";
color: #58daff;
font-size: 44px;
font-style: normal;
position: absolute;
top: 0;
left: 50%;
transform: translate(-50%, 0);
transition: transform 1s ease-in-out;
letter-spacing: 10px;
}
}
}
.number-item:last-child {
margin-right: 0;
}
然后外部使用
<QueryDemandTotal value={"23456"} time={3} />
结束:讲究的就是拿来即用