vue3+elementPlus:实现数字滚动效果(用于大屏可视化)

自行封装注册一个公共组件

案例一:

//成功案例:
//NumberScroll.vue
/*
数字滚动特效组件 NumberScroll
*/<template><span class="number-scroll-grow"><spanref="numberScroll":data-time="time"class="number-scroll":data-value="value">0</span></span>
</template><script>
import { defineComponent } from "vue";
export default defineComponent({name: "numberScroll",props: {time: {type: Number,default: 2,},value: {type: Number,default: 0,},thousandSign: {type: Boolean,default: () => false,},},data() {return {oldValue: 0,};},watch: {value: function (value, oldValue) {this.numberScroll(this.$refs.numberScroll);},},methods: {numberScroll(ele) {let _this = this;let value = _this.value - _this.oldValue;let step = (value * 10) / (_this.time * 100);let current = 0;let start = _this.oldValue;let t = setInterval(function () {start += step;if (start > _this.value) {clearInterval(t);start = _this.value;t = null;}if (current === start) {return;}current = parseInt(start);_this.oldValue = current;if (_this.thousandSign) {ele.innerHTML = current.toString().replace(/(\d)(?=(?:\d{3}[+]?)+$)/g, "$1,");} else {ele.innerHTML = current.toString();}}, 10);},},mounted() {this.$nextTick(() => {this.numberScroll(this.$refs.numberScroll);});},
});
</script><style lang="scss" scoped>
.number-scroll-grow {transform: translateZ(0);
}
</style>//单页面
//html
<div class="count"><!-- 组件 --><numberScroll :value="datalist.equip.realTimeDeviceCount" :time="30"></numberScroll>
</div>

案例二

这个是拉取vue-count-to插件源码,因为这个插件在vue3里不能用

//先在common文件夹建立requestAnimationFrame.js
let lastTime = 0
const prefixes = 'webkit moz ms o'.split(' ') // 各浏览器前缀let requestAnimationFrame
let cancelAnimationFrameconst isServer = typeof window === 'undefined'
if (isServer) {requestAnimationFrame = function () {}cancelAnimationFrame = function () {}
} else {requestAnimationFrame = window.requestAnimationFramecancelAnimationFrame = window.cancelAnimationFramelet prefix// 通过遍历各浏览器前缀,来得到requestAnimationFrame和cancelAnimationFrame在当前浏览器的实现形式for (let i = 0; i < prefixes.length; i++) {if (requestAnimationFrame && cancelAnimationFrame) { break }prefix = prefixes[i]requestAnimationFrame = requestAnimationFrame || window[prefix + 'RequestAnimationFrame']cancelAnimationFrame = cancelAnimationFrame || window[prefix + 'CancelAnimationFrame'] || window[prefix + 'CancelRequestAnimationFrame']}// 如果当前浏览器不支持requestAnimationFrame和cancelAnimationFrame,则会退到setTimeoutif (!requestAnimationFrame || !cancelAnimationFrame) {requestAnimationFrame = function (callback) {const currTime = new Date().getTime()// 为了使setTimteout的尽可能的接近每秒60帧的效果const timeToCall = Math.max(0, 16 - (currTime - lastTime))const id = window.setTimeout(() => {const time = currTime + timeToCallcallback(time)}, timeToCall)lastTime = currTime + timeToCallreturn id}cancelAnimationFrame = function (id) {window.clearTimeout(id)}}
}export { requestAnimationFrame, cancelAnimationFrame }//再在components文件夹建立CountTo.vue
<template><span>{{displayValue}}</span></template><script>import { requestAnimationFrame, cancelAnimationFrame } from '../common/js/requestAnimationFrame.js'export default {props: {startVal: {type: Number,required: false,default: 0},endVal: {type: Number,required: false,default: null},duration: {type: Number,required: false,default: 3000},autoplay: {type: Boolean,required: false,default: true},//小数点位数decimals: {type: Number,required: false,default: 0,validator (value) {return value >= 0}},decimal: {type: String,required: false,default: '.'},separator: {type: String,required: false,default: ','},prefix: {type: String,required: false,default: ''},suffix: {type: String,required: false,default: ''},useEasing: {type: Boolean,required: false,default: true},easingFn: {type: Function,default (t, b, c, d) {return c * (-Math.pow(2, -10 * t / d) + 1) * 1024 / 1023 + b}}},data () {return {localStartVal: this.startVal,displayValue: this.formatNumber(this.startVal),printVal: null,paused: false,localDuration: this.duration,startTime: null,timestamp: null,remaining: null,rAF: null}},computed: {countDown () {return this.startVal > this.endVal}},watch: {startVal () {if (this.autoplay) {this.start()}},endVal () {if (this.autoplay) {this.start()}}},mounted () {if (this.autoplay) {this.start()}this.$emit('mountedCallback')},methods: {start () {this.localStartVal = this.startValthis.startTime = nullthis.localDuration = this.durationthis.paused = falsethis.rAF = requestAnimationFrame(this.count)},pauseResume () {if (this.paused) {this.resume()this.paused = false} else {this.pause()this.paused = true}},pause () {cancelAnimationFrame(this.rAF)},resume () {this.startTime = nullthis.localDuration = +this.remainingthis.localStartVal = +this.printValrequestAnimationFrame(this.count)},reset () {this.startTime = nullcancelAnimationFrame(this.rAF)this.displayValue = this.formatNumber(this.startVal)},count (timestamp) {if (!this.startTime) this.startTime = timestampthis.timestamp = timestampconst progress = timestamp - this.startTimethis.remaining = this.localDuration - progressif (this.useEasing) {if (this.countDown) {this.printVal = this.localStartVal - this.easingFn(progress, 0, this.localStartVal - this.endVal, this.localDuration)} else {this.printVal = this.easingFn(progress, this.localStartVal, this.endVal - this.localStartVal, this.localDuration)}} else {if (this.countDown) {this.printVal = this.localStartVal - ((this.localStartVal - this.endVal) * (progress / this.localDuration))} else {this.printVal = this.localStartVal + (this.endVal - this.localStartVal) * (progress / this.localDuration)}}if (this.countDown) {this.printVal = this.printVal < this.endVal ? this.endVal : this.printVal} else {this.printVal = this.printVal > this.endVal ? this.endVal : this.printVal}this.displayValue = this.formatNumber(this.printVal)if (progress < this.localDuration) {this.rAF = requestAnimationFrame(this.count)} else {this.$emit('callback')}},isNumber (val) {return !isNaN(parseFloat(val))},formatNumber (num) {num = num.toFixed(this.decimals)num += ''const x = num.split('.')let x1 = x[0]const x2 = x.length > 1 ? this.decimal + x[1] : ''const rgx = /(\d+)(\d{3})/if (this.separator && !this.isNumber(this.separator)) {while (rgx.test(x1)) {x1 = x1.replace(rgx, '$1' + this.separator + '$2')}}return this.prefix + x1 + x2 + this.suffix}},unmounted () {cancelAnimationFrame(this.rAF)}}</script>//最后在单文件的html里直接使用
<count-to :
startVal="0" 
:endVal="datalist.equip.realTimeDeviceCount" 
:duration="4000">
</count-to>

上一篇文章,

uniapp踩坑之项目:uni.previewImage简易版预览单图片-CSDN博客文章浏览阅读547次。uniapp踩坑之项目:uni.previewImage简易版预览单图片,主要使用uni.previewImage_uni.previewimagehttps://blog.csdn.net/weixin_43928112/article/details/136565397?spm=1001.2014.3001.5501

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/790179.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

构建知识图谱的基石:理解本体和数据模型

构建知识图谱的基石&#xff1a;理解本体和数据模型 一、本体的基本概念 1. 定义与重要性 本体&#xff08;Ontology&#xff09;在计算机科学和信息科学中&#xff0c;尤其是在知识图谱领域&#xff0c;扮演着重要的角色。它提供了一种形式化的描述知识领域的方法&#xff0…

金融案例:构建高效统一的需求登记与管理方案

在金融行业数字化转型背景下&#xff0c;银行等金融机构面临着业务模式创新与数据应用的深度融合。业务上所需要的不再是单纯的数据&#xff0c;而是数据背后映射的业务趋势洞察&#xff0c;只有和业务相结合转化为业务度量指标&#xff0c;经过数据分析处理呈现为报表进行展示…

【零基础C语言】编译和链接

1.翻译环境和运行环境 翻译环境&#xff1a;将源代码转化为可执行的机器指令 运行环境&#xff1a;用于执行机器指令 1.1 翻译环境 翻译环境由编译和链接两大过程构建&#xff0c;编译又可以分为三大过程&#xff1a; 【1】预处理(预编译) 【2】编译 【3】汇编 不同的.c文件经…

力扣 392. 判断子序列

题目来源&#xff1a;https://leetcode.cn/problems/is-subsequence/description/ C题解1&#xff1a;在t中按顺序一个一个寻找s的元素。 class Solution { public:bool isSubsequence(string s, string t) {bool flg false;int m s.size(), n t.size();if(m 0) return tr…

离散数学【详解】-自学考试湖北,争取做到识字都能看懂。

回顾8年前&#xff0c;我记得我大学高数没复习&#xff0c;考了23分。 今天公司代码写完了&#xff0c;明天清明节&#xff0c;写篇文章磨磨时间。 我的文章&#xff0c;没有一篇不是磨时间能好好写出来的。 ----我 先列标题&#xff0c;比如h1,h2,这些内容。然后往里面填字&a…

面试题:RabbitMQ 消息队列中间件

1. 确保消息不丢失 生产者确认机制 确保生产者的消息能到达队列&#xff0c;如果报错可以先记录到日志中&#xff0c;再去修复数据持久化功能 确保消息未消费前在队列中不会丢失&#xff0c;其中的交换机、队列、和消息都要做持久化消费者确认机制 由spring确认消息处理成功后…

C语言终篇--基于epoll ET模式 的 非阻塞IO服务器模型

使用技术: 1 epoll事件驱动机制&#xff1a;使用epoll作为IO多路复用的技术&#xff0c;以高效地管理多个socket上的事件。 2 边缘触发&#xff08;Edge Triggered, ET&#xff09;模式&#xff1a;epoll事件以边缘触发模式运行&#xff0c;这要求代码必须负责消费所有可用的…

HarmonyOS 应用开发之非线性容器

非线性容器实现能快速查找的数据结构&#xff0c;其底层通过hash或者红黑树实现&#xff0c;包括HashMap、HashSet、TreeMap、TreeSet、LightWeightMap、LightWeightSet、PlainArray七种。非线性容器中的key及value的类型均满足ECMA标准。 HashMap HashMap 可用来存储具有关联…

非线性SVM模型

通过5个条件判定一件事情是否会发生&#xff0c;5个条件对这件事情是否发生的影响力不同&#xff0c;计算每个条件对这件事情发生的影响力多大&#xff0c;写一个非线性SVM模型程序,最后打印5个条件分别的影响力。 示例一 在非线性支持向量机&#xff08;SVM&#xff09;模型中…

Vue3从入门到实战:路由的query和params参数

在Vue 3中&#xff0c;我们可以通过路由的查询参数来传递数据。这意味着我们可以在不同的页面之间传递一些信息&#xff0c;以便页面可以根据这些信息来显示不同的内容或执行不同的操作。 查询参数的使用方式类似于在URL中添加附加信息&#xff0c;以便页面之间可以根据这些信息…

【GlobalMapper精品教程】073:像素到点(Pixels-to-Points)从无人机图像轻松生成点云

文章目录 一、工具介绍二、生成点云三、生成正射四、生成3D模型五、注意事项一、工具介绍 Global Mapper v19引入的新的像素到点工具使用摄影测量原理,从重叠图像生成高密度点云、正射影像及三维模型。它使LiDAR模块成为已经功能很强大的的必备Global Mapper扩展功能。 打开…

JavaScript高级 —— 学习(三)

目录 一、深入面向对象 &#xff08;一&#xff09;面向对象介绍 &#xff08;二&#xff09;面向对象编程 &#xff08;oop&#xff09; 1.面向对象编程介绍 2.面向对象编程优点 3.面向对象的特征 4.和面向过程编程对比 二、构造函数 &#xff08;一&#xff09;介绍…

【HTB】Trick 靶场

Trick靶场 地址&#xff1a;https://app.hackthebox.com/machines/477 打靶过程 靶机IP:10.129.227.180 1.信息收集 1.1 nmap 端口扫描 ┌──(root㉿kali)-[~/Desktop] └─# nmap -Pn -sC -sV -p- 10.129.227.180 --min-rate5000 Starting Nmap 7.94SVN ( https://nmap…

C++——list类及其模拟实现

前言&#xff1a;这篇文章我们继续进行C容器类的分享——list&#xff0c;也就是数据结构中的链表&#xff0c;而且是带头双向循环链表。 一.基本框架 namespace Mylist {template<class T>//定义节点struct ListNode{ListNode<T>* _next;ListNode<T>* _pre…

根据用户角色权限,渲染菜单的一个问题记录

个人博客&#xff1a;无奈何杨&#xff08;wnhyang&#xff09; 个人语雀&#xff1a;wnhyang 共享语雀&#xff1a;在线知识共享 Github&#xff1a;wnhyang - Overview 背景 之前一直讲过自己独立在做一个中后台管理系统&#xff0c;当然这个只是开始&#xff0c;未来会基…

Java复习第十四天学习笔记(CSS),附有道云笔记链接

【有道云笔记】十四 3.30 CSS https://note.youdao.com/s/3VormGXs 一、CSS定义和基本选择器 CSS定义&#xff1a;cascading style sheet 层叠样式表。 语法&#xff1a; 选择器 { 属性名1:属性值1; 属性名2:属性值2; 属性名3:属性值3; 属性名4:属性值4; } CSS使用&a…

实现顺序表(增、删、查、改)

引言&#xff1a;顺序表是数据结构中的一种形式&#xff0c;就是存储数据的一种结构。 这里会用到动态内存开辟&#xff0c;指针和结构体的知识 1.什么是数据结构 数据结构就是组织和存储数据的结构。 数据结构的特性&#xff1a; 物理结构&#xff1a;在内存中存储的数据是否连…

通过vite创建项目

一、VUE3官网 Vue.js - 渐进式 JavaScript 框架 | Vue.js (vuejs.org) 二、通过Vite创建项目 1、在cmd窗口下&#xff0c;全局安装vite //使用国内镜像源 npm config set registryhttps://registry.npmmirror.com//安装最新版vite npm install -g vitelatest Vite | 下一代…

Pygame基础11-mask 蒙版

蒙版 蒙版是二值化的图像&#xff0c;每个像素的值只能是0或1。 mask(蒙版)的用途&#xff1a; 碰撞检测部分着色 案例 和字母的碰撞检测 当玩家碰到字母 α \alpha α时&#xff0c;改变玩家颜色为绿色&#xff0c;否则为红色。 注意&#xff1a;我们希望碰到字母 α \alp…

考研数学1800还是660还是880?

24考完&#xff0c;大家都发现&#xff0c;没有一本习题册&#xff0c;覆盖了考试的所有知识点。 主流的模拟卷&#xff0c;都没有达到24卷的难度。 这就意味着&#xff1a; 一本习题册不够了&#xff01; 刷主流模拟卷不够了&#xff01; 这会需要整个考研复习的安排&…