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.hqwc.cn/news/589821.html

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

相关文章

【C++入门】初识C++

&#x1f49e;&#x1f49e; 前言 hello hello~ &#xff0c;这里是大耳朵土土垚~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#x…

【QT入门】 自定义标题栏界面qss美化+按钮功能实现

往期回顾&#xff1a; 【QT入门】 鼠标按下和移动事件实现无边框窗口拖动-CSDN博客【QT入门】 设计实现无边框窗口拉伸的公用类-CSDN博客【QT入门】对无边框窗口自定义标题栏并实现拖动和拉伸效果-CSDN博客 【QT入门】 自定义标题栏界面qss美化按钮功能实现 一、最终效果 二、…

硬件工程师职责与核心技能有哪些?

作为一个优秀的硬件工程师&#xff0c;必须要具备优秀的职业技能。那么&#xff0c;有些刚入行的工程师及在校的学生经常会问到&#xff1a;硬件工程师需要哪些核心技能&#xff1f;要回答这个问题&#xff0c;首先要明白硬件工程师的职责&#xff0c;然后才能知道核心技能要求…

java回溯算法笔记

回溯算法综述 回溯用于解决你层for循环嵌套问题&#xff0c;且不剪枝的回溯完全等于暴力搜索。 回溯算法模板https://blog.csdn.net/m0_73065928/article/details/137062099?spm1001.2014.3001.5501 组合问题&#xff08;startindex避免使用重复元素&#xff09; “不含重复…

正式签约 | 杭州悦数联袂电子科大重点实验室,打造基于图技术的智慧电网解决方案

近日&#xff0c;杭州悦数科技有限公司与电子科技大学电力系统广域测量与控制四川省重点实验室、四川蓉电科技发展有限公司就电力图计算场景战略达成合作协议&#xff0c;三方于电力系统广域测量与控制四川省重点实验室举行了签约仪式。 正式签约 电力系统广域测量与控制四川…

常见漏洞原理及修复方案

文章目录 前言sql注入sql注入原理sql注入危害sql注入防范sql绕过手法及常见注入手法sqlmap常见使用方法 xssxss原理XSS漏洞危害XSS漏洞分类XSS漏洞测试xss防范 csrf漏洞csrf漏洞原理csrf漏洞流程图csrf漏洞利用条件csrf验证csrf漏洞分类csrf漏洞危害csrf漏洞防范 XXE漏洞XXE漏洞…

mysql 磁盘空间100%

MySQL大事务可能会导致过多的占用临时文件&#xff0c;导致磁盘空间撑满的问题 本例说明下binlog cache产生的临时文件 案例复现 调小binlog_cache_size&#xff0c;让DML使用临时文件 使用存储过程模拟大事务 创建表 create table t1( id int AUTO_INCREMENT, name varchar…

地表径流分布数据/水文站点分布/降雨量分布/辐射分布数据

引言 大气降水落到地面后&#xff0c;一部分蒸发变成水蒸气返回大气&#xff0c;一部分下渗到土壤成为地下水&#xff0c;其余的水沿着斜坡形成漫流&#xff0c;通过冲沟&#xff0c;溪涧&#xff0c;注入河流&#xff0c;汇入海洋。这种水流称为地表径流。 正文 数据简介 来自…

[力扣]根据前中序构造二叉树--详细解析

根据前中序遍历顺序构建一个二叉树 力扣练习链接 过程 总体框架 设preorder的左边界为pleft,右边界为pright[注意这里是闭区间能取到]同时设inorder的左边界为ileft,有边界为iright[同样也是可以取到的索引区间]我们生成每一个区间的树的头结点,然后向上返回,对于他的父亲结点…

非关系型数据库-----------Redis的主从复制、哨兵模式

目录 一、redis群集有三种模式 1.1主从复制、哨兵、集群的区别 1.1.1主从复制 1.1.2哨兵 1.1.3集群 二、主从复制 2.1主从复制概述 2.2主从复制的作用 ①数据冗余 ②故障恢复 ③负载均衡 ④高可用基石 2.3主从复制流程 2.4搭建redis主从复制 2.4.1环境准备 2.4…

mysql计划事件即定时任务的实现

目录 前言设置系统参数创建计划事件时间间隔举例 前言 在MySQL中&#xff0c;创建一个定时任务&#xff08;即“计划事件”&#xff09;通常涉及使用EVENT对象。有些时候使用mysql定时任务做一些批量处理是非常方便的&#xff0c;比如每天零晨记录头天的库存数据&#xff0c;发…

南京大学提出用于大模型生成的动态温度采样法,简单有效!

在自然语言处理&#xff08;NLP&#xff09;的领域&#xff0c;大语言模型&#xff08;LLMs&#xff09;已经在各种下游语言任务中展现出了卓越的性能。这些任务包括但不限于问答、摘要、机器翻译等。LLMs的强大能力在于其生成的文本质量和多样性。为了控制生成过程&#xff0c…