從數字漸變組件(countUp.js)談第三方JS庫的使用
1、組件封裝基礎
實例
父組件count-to.vue:
<template>
<div>
// 父組件獲取DOM通過ref屬性,父組件傳遞給子組件end-val屬性
<count-to ref="countTo" :end-val="endVal" @on-animation-end="handleEnd">
<span slot="left">總金額: </span>
<span slot="right">元</span>
</count-to>
<button @click="getNumber">獲取數值</button>
<button @click="up">更新值</button>
</div>
</template>
<script>
import CountTo from '@/components/count-to'
export default {
name: 'count_to',
components: {
CountTo
},
data () {
return {
endVal: 100
}
},
methods: {
getNumber () {
this.$refs.countTo.getCount()
},
up () {
this.endVal += Math.random() * 100
},
handleEnd (endVal) {
console.log('end -> ', endVal)
}
}
}
</script>
子組件count-to.vue:
<template>
<div>
<slot name="left"></slot>
<span ref="number" :class="countClass" :id="eleId"></span>
<slot name="right"></slot>
</div>
</template>
<script>
import CountUp from 'countup'
export default {
name: 'CountTo',
computed: {
eleId () {
// 當組件編譯時會生成當前編譯實例的id
return `count_up_${this._uid}`
},
countClass () {
return [
'count-to-number',
this.className
]
}
},
data () {
return {
counter: {}
}
},
// 接收父組件傳遞的參數
props: {
/**
* @description 起始值
*/
startVal: {
type: Number,
default: 0
},
/**
* @description 最終值
*/
endVal: {
type: Number,
required: true
},
/**
* @description 小數點後保留幾位小數
*/
decimals: {
type: Number,
default: 0
},
/**
* @description 動畫延遲開始時間
*/
delay: {
type: Number,
default: 0
},
/**
* @description 漸變時長
*/
duration: {
type: Number,
default: 1
},
/**
* @description 是否使用變速效果
*/
useEasing: {
type: Boolean,
default: false
},
/**
* @description 是否使用變速效果
*/
useGrouping: {
type: Boolean,
default: true
},
/**
* @description 分組符號
*/
separator: {
type: String,
default: ','
},
/**
* @description 整數和小數分割符號
*/
decimal: {
type: String,
default: '.'
},
className: {
type: String,
default: ''
}
},
methods: {
getCount () {
return this.$refs.number.innerText
},
emitEndEvent () {
setTimeout(() => {
this.$nextTick(() => {
// this.$emit調用父組件綁定的函數
this.$emit('on-animation-end', Number(this.getCount()))
})
}, this.duration * 1000 + 5)
}
},
watch: {
endVal (newVal, oldVal) {
this.counter.update(newVal)
this.emitEndEvent()
}
},
mounted () {
this.$nextTick(() => {
// 這個是實例化CountUp插件
this.counter = new CountUp(this.eleId, this.startVal, this.endVal, this.decimals, this.duration, {
useEasing: this.useEasing,
useGrouping: this.useGrouping,
separator: this.separator,
decimal: this.decimal
})
setTimeout(() => {
this.counter.start()
this.emitEndEvent()
}, this.delay)
})
}
}
</script>
<style lang="less">
@import './count-to.less';
</style>
2、組件中使用id值
從上面代碼可以看出每次編譯Vue組件的時候都會生成_uid標識符,並且這個_uid在相同組件的不同實例中都不一樣
3、組件中獲取DOM
在組件上添加ref屬性,獲取DOM的時候用this.$refs