Vue3实现基于jsx的Ts版数字自动增长组件

82 阅读1分钟

先看效果图

具体实现

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} />

结束:讲究的就是拿来即用