本文主要从数字渐变组件谈第三方JS库的使用
在views文件夹下新建count-to页面
在路由中进行配置
{
path: '/count-to',
name: 'count-to',
component: () => import('@/views/count-to.vue')
},
组件封装需要放在components文件夹下,我们在components文件夹下创建count-to文件夹并创建count-to文件
<template>
<div>
</div>
</template>
<script>
export default {
name: 'countTo'
}
</script>
在count-to文件夹下创建index.js文件并进行配置,目的是为了便于引入(可以用‘@/components/count-to’引入)
import CountTo from './count-to.vue'
export default CountTo
在(views)count-to页面组件引入
<template>
<div>
<count-to></count-to>
</div>
</template>
<script>
import CountTo from '@/components/count-to'
export default {
name: 'count_to',
components: {
CountTo
}
}
</script>
安装js库,并在(components)组件中引入并进行配置
countup官方链接.
countup教程解析.
npm install vue-countupjs
<template>
<div>
<span :id="eleId"></span>
</div>
</template>
<script>
import CountUp from 'countup'
export default {
name: 'CountTo',
// 使用计算属性确保id值不重复
computed: {
eleId () {
// 可以根据每个组件的uid都不相同
return `count_up_${this._uid}`
}
},
// 由于创建的实例在后面需要调用方法,所以把创建的实例存在data中
data () {
return {
counter: {}
}
},
props: {
// 动画延迟自定义事件(自定义属性)
delay: {
type: Number,
default: 0
},
startVal: {
type: Number,
default: 0
},
endVal: {
type: Number,
require: true
},
decimals: {
type: Number,
default: 0
},
duration: {
type: Number,
default: 1
},
useEasing: {
type: Boolean,
default: false
},
useGrouping: {
type: Boolean,
default: true
},
separator: {
type: String,
default: ','
},
decimal: {
type: String,
default: '.'
}
},
// mounted生命周期钩子会在实例挂载到html标签后触发
mounted () {
// 当页面上的所有dom都渲染完之后会调用这个回调函数
this.$nextTick(() => {
// 创建实例
// 第一个参数为target用来匹配id值,通过计算属性可以解决id值的问题
// 第二个参数为startVal,用来定义起始值(通过props属性传入)
// 第三个参数为endVal,用来定义最终值
// 第四个参数decimals用来定义小数点后保留几位
// 第五个参数duration表示动画持续时间
// 第六个参数为一个配置对象
// 第一个参数useEasing设置变化速度 true为变速 false为匀速
// 第二个参数useGrouping设置分组效果 true为变速 false为匀速
// 第三个参数separatot设置分组符号
// 第四个参数decimal设置小数分组符号
this.counter = new CountUp(this.eleId, this.startVal, this.endVal, this.decimals, this.duration, {
useEasing: this.useEasing,
useGrouping: this.useGrouping,
separator: ',',
decimal: '.'
})
setTimeout(() => {
this.counter.start()
}, this.delay)
})
}
}
</script>
在views中
<template>
<div>
<count-to :end-val='100'></count-to>
</div>
</template>
<script>
import CountTo from '@/components/count-to'
export default {
name: 'count_to',
components: {
CountTo
}
}
</script>
1.单个插槽
在components的组件中定义如下
<slot></slot><span :class="countClass" :id="eleId"></span>
在views页面组件中使用时候
<template>
<div>
<count-to :end-val='100'>
<span>金额</span>
</count-to>
</div>
</template>
2.多个插槽,使用具名属性
在components的组件中定义如下
<template>
<div>
<slot name='left'></slot><span :class="countClass" :id="eleId"></span><slot name='right'></slot>
</div>
</template>
在views页面组件中使用时候,对应slot属性
<template>
<div>
<count-to :end-val='100'>
<span slot="left">金额</span>
<span slot="right">元</span>
</count-to>
</div>
</template>
首先我们使用ref为标签定义一个名字
<span ref="number" :class="countClass" :id="eleId"></span>
在methods中使用getCount方法获取dom元素中的值
methods: {
// 获取当前span标签显示的数值
getCount () {
return this.$refs.number.innerText
}
}
接下来在父组件中调用,同样定义一个ref
<count-to ref="countTo" :end-val='100'>
<span slot="left">金额</span>
<span slot="right">元</span>
</count-to>
在methods中定义方法
ref如果设置在组件上则获取组件实例,设置在标签上则获取dom对象
methods: {
getNumber () {
// 获取实例后调用实例上的getCount方法
this.$refs.countTo.getCount()
}
}
触发
<button @click="getNumber">获取数值</button>
由于该方法需要在endVal后调用,这里我们使用监听器watch(在components组件页面中)
watch: {
endVal (newVal, oldVal) {
// 使用js库中提供的update方法
this.counter.update(newVal)
}
}
在父组件(views)中配置
// 绑定一个值
<count-to ref="countTo" :end-val='endVal'>
<span slot="left">金额</span>
<span slot="right">元</span>
</count-to>
data () {
return {
endVal: 100
}
}
methods: {
up () {
this.endVal += Math.random() * 100
}
}
<button @click="up">更新值</button>
methods: {
// 获取当前span标签显示的数值
getCount () {
return this.$refs.number.innerText
},
emitEndEvent () {
setTimeout(() => {
this.$nextTick(() => {
this.$emit('on-animation-end', Number(this.getCount()))
})
}, this.duration * 1000 + 5)
}
},
watch: {
endVal (newVal, oldVal) {
this.counter.update(newVal)
this.emitEndEvent()
}
}
views部分
<count-to ref="countTo" :end-val='endVal' @on-animation-end='handleEnd'>
<span slot="left">金额</span>
<span slot="right">元</span>
</count-to>
methods: {
getNumber () {
console.log(this.$refs.countTo.getCount())
},
up () {
this.endVal += Math.random() * 100
},
handleEnd (endVal) {
console.log('end —> ', endVal)
}
}
在components文件夹下的count-to文件夹中新建count-to.sass,配置后在组件文件中导入
在组件中配置类名
<slot name='left'></slot><span ref="number" :class="countClass" :id="eleId"></span><slot name='right'></slot>
computed: {
countClass () {
return [
//组件固有类名
'count-to-number',
//组件传入使用的类名
this.className
]
}
}
props: {
className: {
type: String,
default: ''
}
}
import './count-to.sass'
sass文件中
.count-to-number
color: red
<template>
<div>
<count-to ref="countTo" :end-val='endVal' @on-animation-end='handleEnd'>
<span slot="left">金额</span>
<span slot="right">元</span>
</count-to>
<count-to ref="countTo" :end-val='endVal' @on-animation-end='handleEnd' :class="className">
<span slot="left">金额</span>
<span slot="right">元</span>
</count-to>
<button @click="getNumber">获取数值</button>
<button @click="up">更新值</button>
</div>
</template>
在views页面引用组件中定义类名
data () {
return {
className: 'dada'
}
},
sass文件中
.count-to-number
color: red
.dada
font-size: 20px