vue3使⽤vue-count-to组件
项⽬场景:
数据可视化⼤屏开发的过程中,需要实现⼀种滚动数字的效果,在使⽤vue2时,使⽤完全没有问题,功能也⽐较完善(滚动时长,开始值,结束值,前缀,后缀,千分隔符,⼩数分隔符等等),但是在vue3中使⽤会出现问题。
<template>
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>
<count-to :startVal="0":endVal="2045":duration="4000"></count-to>
<router-view/>
</template>
展⽰的效果
问题描述:
出现的错误时 Cannot read property ‘_c’ of undefined 这是⼀个_c的属性没有到,具体的情况也不是很清楚。在vue-count-to打包后的源码中可以⼤致看出来,这是在render函数中出现的错误。但是还是没法下⼿。
解决⽅案:
采⽤的⽅法是直接复制node_modules下vue-count-to的源⽂件(src下),到⾃⼰项⽬的components下。如图
然后根据eslint的检查,修改代码,直到不报错,且记删除package.json下刚刚引⼊的vue-count-to的依赖。如图
最后重启项⽬。
vue-count-to组件 vue3使⽤
vue-count-to源码
let lastTime =0
const prefixes ='webkit moz ms o'.split(' ')// 各浏览器前缀
let requestAnimationFrame
let cancelAnimationFrame
const isServer =typeof window ==='undefined'
if(isServer){
requestAnimationFrame=function(){
}
cancelAnimationFrame=function(){
}
}else{
requestAnimationFrame = questAnimationFrame
cancelAnimationFrame = window.cancelAnimationFrame
let 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,则会退到setTimeout
if(!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 + timeToCall
callback(time)
}, timeToCall)
lastTime = currTime + timeToCall
return id
}
cancelAnimationFrame=function(id){
window.clearTimeout(id)
}
}
}
export{ requestAnimationFrame, cancelAnimationFrame }
<template>
<span>
{{displayValue}}
</span>
</template>
<script>
import{ requestAnimationFrame, cancelAnimationFrame }from'./requestAnimationFrame.js'
export default{
props:{
startVal:{
type: Number,
required:false,
default:0
},
endVal:{
type: Number,
required:false,
default:2017
},
duration:{
type: Number,
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,formatnumber数字格式
remaining:null,
rAF:null
}
},
computed:{
countDown(){
return this.startVal &dVal
}
},
watch:{
startVal(){
if(this.autoplay){
this.start()
}
},
endVal(){
if(this.autoplay){
this.start()
}
}
},
mounted(){
if(this.autoplay){
if(this.autoplay){
this.start()
}
this.$emit('mountedCallback')
},
methods:{
start(){
this.localStartVal =this.startVal
this.startTime =null
this.localDuration =this.duration
this.paused =false
this.rAF =unt)
},
pauseResume(){
if(this.paused){
this.paused =false
}else{
this.pause()
this.paused =true
}
},
pause(){
cancelAnimationFrame(this.rAF)
},
resume(){
this.startTime =null
this.localDuration =+aining
this.localStartVal =+this.printVal
unt)
},
reset(){
this.startTime =null
cancelAnimationFrame(this.rAF)
this.displayValue =this.formatNumber(this.startVal)
},
count(timestamp){
if(!this.startTime)this.startTime = timestamp
this.timestamp = timestamp
const progress = timestamp -this.startTime
if(this.useEasing){
untDown){
this.printVal =this.localStartVal -this.easingFn(progress,0,this.localStartVal -dVal,this.localDuration) }else{
this.printVal =this.easingFn(progress,this.dVal -this.localStartVal,this.localDuration) }
}else{
untDown){
this.printVal =this.localStartVal -((this.localStartVal -dVal)*(progress /this.localDuration))
}else{
this.printVal =this.localStartVal +(dVal -this.localStartVal)*(progress /this.localDuration)
}
}
untDown){
this.printVal =this.printVal &dVal ?dVal :this.printVal
}else{
this.printVal =this.printVal &dVal ?dVal :this.printVal
}
this.displayValue =this.formatNumber(this.printVal)
if(progress <this.localDuration){
this.rAF =unt)
}else{
this.$emit('callback')
}
},
isNumber(val){
return!isNaN(parseFloat(val))
},
formatNumber(num){
num = Fixed(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)){
st(x1)){

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。