vue3.0翻牌数字组件使用方法详解

本文实例为大家分享了vue3.0翻牌数字组件使用的具体代码,供大家参考,具体内容如下

代码

<template>
  <div class="number-count-wrap" :class="numberSize">
    <!-- 标题 start -->
    <div class="number-title" :style="{'text-align': titleAlign}">{{title}}</div>
    <!-- 标题 end -->
    <div class="number-count" :class="numberAlign">
      <!-- 计数器 start -->
      <ul class="number-content">
        <template v-for="(item,index) in orderNum"
          :key="index">
        <li class="number-item" v-if="!isNaN(item)">
          <span>
            <ul class="number-list" :ref="numberItem">
              <li>0</li>
              <li>1</li>
              <li>2</li>
              <li>3</li>
              <li>4</li>
              <li>5</li>
              <li>6</li>
              <li>7</li>
              <li>8</li>
              <li>9</li>
            </ul>
          </span>
        </li>
        <li class="separator" v-else>
          {{item}}
        </li>
        </template>
      </ul>
      <!-- 计数器 end -->
      <!-- 单位 start -->
      <div class="number-unit" v-if="unit">{{unit}}</div>
      <!-- 单位 end -->
    </div>
  </div>
</template>

<script>
import { onMounted, watch, ref, reactive, toRefs } from 'vue'
export default {
  name: "numberCount",
  props: {
    numberSize: { // 字号大小 middle 中号 small 小号
      type: String,
      default: ''
    },
    title: { // 标题
      type: String,
      default: ""
    },
    titleAlign: { // 标题对齐方式
      type: String,
      default: ''
    },
    numberAlign: { //数字对齐方式
      type: String, // center 居中对齐
      default: ''
    },
    unit: { // 单位
      type: String,
      default: ""
    },
    countNum: { // 数值
      type: Number,
    },
    initDelay: { // 首次加载延时
      type: Number,
    }
  },
  setup(props) {
    const numberItemList = ref([]);
    const numberItem = (el) => {
      numberItemList.value.push(el);
    };
    var locarCountNum = props.countNum.toLocaleString()
    locarCountNum = locarCountNum.split('')
    const data = reactive({
      orderNum: locarCountNum, // 默认订单总数
    });
    watch(props, (nval, oval) => {
      if (nval) {
        toOrderNum(nval.countNum)
      }
    })
    onMounted(() => {
      setTimeout(() => {
        toOrderNum(props.countNum) // 这里输入数字即可调用
      }, props.initDelay);
    })
    function setNumberTransform () {
      const numberItems = numberItemList.value // 拿到数字的ref,计算元素数量
      const numberArr = data.orderNum.filter(item => !isNaN(item))
      // 结合CSS 对数字字符进行滚动,显示订单数量
      for (let index = 0; index < numberItems.length; index++) {
        const elem = numberItems[index]
        elem.style.transform = `translate(0%, -${numberArr[index] * 10}%)`
      }
    }
    // 处理总订单数字
    function toOrderNum(num) {
      // console.log('num',num)
      // num = num.toString()
      // 把订单数变成字符串
      // if (num.length < 7) {
      //   num = '0' + num // 如未满八位数,添加"0"补位
      //   toOrderNum(num) // 递归添加"0"补位
      // } else if (num.length === 7) {
      //   // 订单数中加入逗号
      //   // num = num.slice(0, 2) + ',' + num.slice(2, 5) + ',' + num.slice(5, 8)
      //   data.orderNum = num.split('') // 将其便变成数据,渲染至滚动数组
      // } else {
      //   // 订单总量数字超过八位显示异常
      //   // _this.$message.warning('总量数字过大')
      // }
      setNumberTransform()
    }
    return {
      setNumberTransform,
      toOrderNum,
      numberItem,
      ...toRefs(data)
    }
  }
};
</script>
<style scoped lang="less">
.number-count-wrap {
  .number-title {
    font-size: .18rem;
    color: #FFFFFF;
    line-height: 1;
    margin-bottom: .15rem;
    font-weight: bold;
  }
  .number-count {
    display: flex;
    justify-content: flex-start;
    align-items: flex-end;
    .number-content {
      display: flex;
      justify-content: flex-start;
      align-items: center;
        /*文字禁止编辑*/
      -moz-user-select: none; /*火狐*/
      -webkit-user-select: none; /*webkit浏览器*/
      -ms-user-select: none; /*IE10*/
      -khtml-user-select: none; /*早期浏览器*/
      user-select: none;
      .number-item {
        width: 0.32rem;
        // height: 1.8rem;
        display: flex;
        justify-content: center;
        align-items: center;
        margin: 0 0.02rem;
        &>span {
          position: relative;
          display: inline-block;
          width: 100%;
          height: 0.4rem;
          overflow: hidden;
          background: linear-gradient(180deg, #2167D0 0%, #164D8F 100%);
          box-shadow: 0 .04rem 0 0 #176ED6;
          border-radius: .06rem;
          border: 1px solid white;
          padding-bottom: .04rem;
          box-sizing: border-box;
          .number-list{
            transition: transform 1s ease-in-out;
            text-align: center;
            font-weight: 600;
            li {
              height: 0.4rem;
              display: flex;
              justify-content: center;
              align-items: center;
              font-size: .3rem;
              font-weight:400;
              color: white;
              padding-bottom: .04rem;
              box-sizing: border-box;
            }
          }
        }
      }
      .separator {
        font-size: .3rem;
        font-weight: normal;
        color: #FFFFFF;
        line-height: 1;
        margin: 0 0.025rem;
      }
    }
    .number-unit {
      margin-left: .1rem;
      font-size: .18rem;
      font-weight: normal;
      color: #B1B7BC;
    }
  }
  .center {
    justify-content: center;
  }
}

// middle start
.middle {
  .number-title {
    font-size: .12rem;
    margin-bottom: .10rem;
  }
  .number-count {
    .number-content {
      .number-item {
        width: 0.2rem;
        margin: 0 0.0175rem;
        &>span {
          height: 0.25rem;
          box-shadow: 0 .025rem 0 0 #176ED6;
          border-radius: .04rem;
          padding-bottom: .025rem;
          .number-list{
            li {
              height: 0.25rem;
              font-size: .2rem;
              font-weight:400;
              color: white;
              box-sizing: border-box;
            }
          }
        }
      }
      .separator {
        font-size: .2rem;
        margin: 0 0.025rem;
      }
    }
    .number-unit {
      margin-left: .06rem;
      font-size: .12rem;
    }
  }
}
// middle end
</style>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • vue实现数字动态翻牌器

    数字动态翻牌器 最近项目里使用到了数字翻牌器,于是自己写了一个,动态的翻牌器 第一步创建一个组件页面,NumberCount.vue 思路:大概就是显示几位数,然后从0开始滚动到当前的数值的位置,在每一个位置都有0-9的数,然后就是往上滚动当前数值的次数到当前的数,话不多说上代码 <template>   <div class="chartNum">     <div class="box-item">       <li

  • vue版数字翻牌器的封装

    本文实例为大家分享了vue版数字翻牌器的封装代码,供大家参考,具体内容如下 封装vue版数字翻牌器 <template>      <div class="number">          <ul id="dataNums">              <li v-for="(item,index) in list" :key="index">                 

  • vue实现翻牌动画

    本文实例为大家分享了vue实现翻牌动画的具体代码,供大家参考,具体内容如下 应用场景 常用于大屏订单数量展示 原理 利用css writing-mode: vertical-rl 使数字垂直排列 利用css transform 使数字滚动 实现思路 根据css先让数字垂直排列,总共设置8列 根据组件传递的数值,如果不满8位,递归补零 补零之后,循环根据 translate(-50%, -${numberArr[index] * 10}%,查看动画 <template>     <div

  • vue实现数字动态翻牌的效果(开箱即用)

    实现效果图 原理 将1~9的数字竖直排版,通过translate移动位置显示不同数字,使用transition控制transform属性有动画效果 技术点 css 属性 writing-mode: vertical-lr,使数字竖直排版 移动  transform: translate(-50%, -40%); y值控制移动至哪个数字 transition  控制transform属性有动画效果 实现代码(注释比较详细,不再赘述) <!-- * @Author: mat * @Date: 201

  • vue3.0翻牌数字组件使用方法详解

    本文实例为大家分享了vue3.0翻牌数字组件使用的具体代码,供大家参考,具体内容如下 代码 <template>   <div class="number-count-wrap" :class="numberSize">     <!-- 标题 start -->     <div class="number-title" :style="{'text-align': titleAlign}&q

  • Vue3.0版本强势升级点特性详解

    目录 一.Composition API: 组合API/注入API 二.自定义渲染API(Custom Renderer API) vue2.x架构问题 三.更先进的组件 Fragment组件 Suspense组件 四.更好的TS支持 五.更快的开发体验(vite开发构建工具) 六.按需编译,体积比Vue2.x更小(Tree shaking) 七.性能比2.x快1.2-2倍 diff算法的优化 render阶段的静态提升(render阶段指生成虚拟dom树的阶段) 事件侦听缓存 减少创建组件实例

  • 利用Vue3实现可复制表格的方法详解

    目录 前言 最基础的表格封装 实现复制功能 处理表格中的不可复制元素 测试 前言 表格是前端非常常用的一个控件,但是每次都使用v-for指令手动绘制tr/th/td这些元素是非常麻烦的.同时,基础的 table 样式通常也是不满足需求的,因此一个好的表格封装就显得比较重要了. 最基础的表格封装 最基础基础的表格封装所要做的事情就是让用户只关注行和列的数据,而不需要关注 DOM 结构是怎样的,我们可以参考 AntDesign,columns dataSource 这两个属性是必不可少的,代码如下:

  • Python实现猜拳与猜数字游戏的方法详解

    至此,我们的 Python零基础入门篇 的系列专栏到今天基本上算是结束了.今天没有任何的知识点,只是运用我们之前学习过的知识做两个小游戏的案例.第一个是模拟猜拳的小游戏,第二个就是猜数字的游戏. 猜拳小游戏 需求: 运用至今所学的 Python 知识编写脚本,实现一个人与计算机玩猜拳的石头剪刀布的小游戏. 这里我们先思考一下,如果将石头.剪刀.布分别用数字0.1.2表示,那么如何判定谁胜谁负呢? user robot 结果 0(石头) 0(石头) 平局 0(石头) 1(剪刀) user 获胜 0

  • Python+OpenCV实现信用卡数字识别的方法详解

    目录 一.模板图像处理 二.信用卡图片预处理 一.模板图像处理 (1)灰度图.二值图转化 template = cv2.imread('C:/Users/bwy/Desktop/number.png') template_gray = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY) cv_show('template_gray', template_gray) # 形成二值图像,因为要做轮廓检测 ret, template_thresh = cv2.thre

  • mysql8.0.19忘记密码处理方法详解

    1在配置文件中添加skip-grant-tables后重启mysql,然后直接登录 [root@tyjs09 ~]# cat /etc/my.cnf [mysqld] user=mysql basedir=/application/mysql datadir=/data/mysql/data socket=/tmp/mysql.sock server_id=6 port=3306 gtid-mode=on enforce-gtid-consistency=true log_error=/data

  • Vue使用Swiper封装轮播图组件的方法详解

    目录 Swiper 为什么要封装组件 开始封装 1.下载安装Swiper 2.引入css样式文件 3.引入js文件 4.把官网使用方法中的HTML结构复制粘贴过来 5.初始化Swiper 自定义效果 完整代码 效果展示 Swiper Swiper是一个很常用的用于实现各种滑动效果的插件,PC端和移动端都能很好的适配. 官网地址:www.swiper.com.cn/ 目前最新版本是Swiper7,但众所周知最新版本通常不稳定,所以这里使用Swiper6来封装. Swiper各版本区别: 为什么要封

  • vue全局组件与局部组件使用方法详解

    vue全局/局部注册,以及一些混淆的组件 main.js入口文件的一些常用配置, 在入口文件上定义的public.vue为全局组件,在这里用的是pug模版 .wraper 的形式相当于<div class=wraper></div> -main.js文件 **main.js入口文件的内容** import Vue from 'vue' import App from './App' import router from './router' // 引入公用组件的vue文件 他暴漏的

  • 微信小程序带动画弹窗组件使用方法详解

    本文实例为大家分享了微信小程序带动画弹窗的具体代码,供大家参考,具体内容如下 基本效果如下: 具体实现如下: 第一步: 新建一个 components 文件夹,用于存放我们以后开发中的所用组件,在 components 组件中新建一个popup文件夹来存放我们的弹窗组件,在popup下右击新建 Component 并命名为 popup 后,会生成对应的 json wxml wxss js 4个文件,也就是一个自定义组件的组成部分,此时项目结构应该如下图所示: 第二步上代码: popup.wxml

  • 微信小程序自定义toast组件的方法详解【含动画】

    本文实例讲述了微信小程序自定义toast组件的方法.分享给大家供大家参考,具体如下: 怎么创建就不说了,前面一篇有 微信小程序自定义prompt组件 直接上代码 wxml <!-- components/toast/toast.wxml --> <view class="toast-box {{isShow? 'show':''}}" animation="{{animationData}}"> <view class="to

随机推荐