Vue3基于countUp.js怎么实现数字滚动的插件

前端开发   发布日期:前天 08:38   浏览次数:126

这篇文章主要介绍“Vue3基于countUp.js怎么实现数字滚动的插件”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Vue3基于countUp.js怎么实现数字滚动的插件”文章能帮助大家解决问题。

countUp 简介

CountUp.js 是一种无依赖项的轻量级 JavaScript 类,可用于快速创建以更有趣的方式显示数字数据的动画。CountUp 可以在两个方向上进行计数,具体取决于传递的开始和结束值。

虽然现在市面上基于 countUp.js 二次封装的Vue组件不在少数, 但我个人是不太喜欢使用这些第三方封装的,因为第三方组件的更新频率很难保证,也许作者只是一时兴起封装上传了, 并未打算继续维护,如果使用了 等于后续根本没有维护性了, 所以这种二次封装我推荐自行实现, 我们可以通过本次封装熟悉一下

  1. vue3
,
  1. ts
的语法

countUp 组件封装

首先进行安装

  1. npm i countup.js

安装好之后新建文件

  1. CountUp.vue
, template部分很简单, 只需要一个
  1. span
标签, 同时给
  1. span
一个
  1. ref='countupRef'
就完成了,首先引入
  1. countup.js
, 按住Ctrl鼠标左键点击Countup.js可以看到 d.ts文件,
  1. countUp.d.ts
如下
  1. export interface CountUpOptions {
  2. startVal?: number;
  3. decimalPlaces?: number;
  4. duration?: number;
  5. useGrouping?: boolean;
  6. useIndianSeparators?: boolean;
  7. useEasing?: boolean;
  8. smartEasingThreshold?: number;
  9. smartEasingAmount?: number;
  10. separator?: string;
  11. decimal?: string;
  12. easingFn?: (t: number, b: number, c: number, d: number) => number;
  13. formattingFn?: (n: number) => string;
  14. prefix?: string;
  15. suffix?: string;
  16. numerals?: string[];
  17. enableScrollSpy?: boolean;
  18. scrollSpyDelay?: number;
  19. scrollSpyOnce?: boolean;
  20. onCompleteCallback?: () => any;
  21. plugin?: CountUpPlugin;
  22. }
  23. export declare interface CountUpPlugin {
  24. render(elem: HTMLElement, formatted: string): void;
  25. }
  26. export declare class CountUp {
  27. private endVal;
  28. options?: CountUpOptions;
  29. version: string;
  30. private defaults;
  31. private rAF;
  32. private startTime;
  33. private remaining;
  34. private finalEndVal;
  35. private useEasing;
  36. private countDown;
  37. el: HTMLElement | HTMLInputElement;
  38. formattingFn: (num: number) => string;
  39. easingFn?: (t: number, b: number, c: number, d: number) => number;
  40. error: string;
  41. startVal: number;
  42. duration: number;
  43. paused: boolean;
  44. frameVal: number;
  45. once: boolean;
  46. constructor(target: string | HTMLElement | HTMLInputElement, endVal: number, options?: CountUpOptions);
  47. handleScroll(self: CountUp): void;
  48. /**
  49. * Smart easing works by breaking the animation into 2 parts, the second part being the
  50. * smartEasingAmount and first part being the total amount minus the smartEasingAmount. It works
  51. * by disabling easing for the first part and enabling it on the second part. It is used if
  52. * usingEasing is true and the total animation amount exceeds the smartEasingThreshold.
  53. */
  54. private determineDirectionAndSmartEasing;
  55. start(callback?: (args?: any) => any): void;
  56. pauseResume(): void;
  57. reset(): void;
  58. update(newEndVal: string | number): void;
  59. count: (timestamp: number) => void;
  60. printValue(val: number): void;
  61. ensureNumber(n: any): boolean;
  62. validateValue(value: string | number): number;
  63. private resetDuration;
  64. formatNumber: (num: number) => string;
  65. easeOutExpo: (t: number, b: number, c: number, d: number) => number;
  66. }

这里 export 了一个

  1. CountUp
类 还有一个
  1. CountUpOptions
的interface,
  1. CountUp
类的
  1. constructor
接收三个参数, 分别是 dom节点, endVal, 以及 options, 我们将这三个参数当成是
  1. props
传入同时给定默认值, , 首先获取span的ref作为
  1. countUp
初始化的容器 , 定义一个变量
  1. numAnim
接收
  1. new CountUp(countupRef.value, props.end, props.options)
的返回值, , 在
  1. onMounted
中初始化
  1. countUp.js
,接着我们就可以去页面引入
  1. CountUp.vue
看看效果,因为有默认值,所以我们不需要传入任何参数, 直接看就好了, 此时
  1. CountUp.vue
组件代码如下,
  1. <script setup lang="ts">
  2. import { CountUp } from 'countup.js'
  3. import type { CountUpOptions } from 'countup.js'
  4. import { onMounted, ref } from 'vue'
  5. let numAnim = ref(null) as any
  6. const countupRef = ref()
  7. const props = defineProps({
  8. end: {
  9. type: Number,
  10. default: 2023
  11. },
  12. options: {
  13. type: Object,
  14. default() {
  15. let options: CountUpOptions = {
  16. startVal: 0, // 开始的数字 一般设置0开始
  17. decimalPlaces: 2, // number类型 小数位,整数自动添.00
  18. duration: 2, // number类型 动画延迟秒数,默认值是2
  19. useGrouping: true, // boolean类型 是否开启逗号,默认true(1,000)false(1000)
  20. useEasing: true, // booleanl类型 动画缓动效果(ease),默认true
  21. smartEasingThreshold: 500, // numberl类型 大于这个数值的值开启平滑缓动
  22. smartEasingAmount: 300, // numberl类型
  23. separator: ',',// string 类型 分割用的符号
  24. decimal: '.', // string 类型 小数分割符合
  25. prefix: '¥', // sttring 类型 数字开头添加固定字符
  26. suffix: '元', // sttring类型 数字末尾添加固定字符
  27. numerals: [] // Array类型 替换从0到9对应的字,也就是自定数字字符了,数组存储
  28. }
  29. return options
  30. }
  31. }
  32. })
  33. onMounted(() => {
  34. initCount()
  35. })
  36. const initCount = () => {
  37. numAnim = new CountUp(countupRef.value, props.end, props.options)
  38. numAnim.start()
  39. }
  40. </script>
  41. <template>
  42. <span ref="countupRef"></span>
  43. </template>

这时我们发现,在

  1. onMounted
执行之后, 如果我们的endVal值发生了改动, 由于
  1. CountUp.vue
  1. onMounted
已经完成,并不会同步修改, 如果我们的值是异步获取的,会造成渲染不出我们想要的结果,那么我们就需要在组件中把这个
  1. initCount
方法给暴露给父组件使用,在vue3中,我们只需要使用
  1. defineExpose
暴露即可, 同时我们也进一步完善一下我们的props, 校验限制一下传入的
  1. optinos
值, 尽量避免使用上的错误, 同时修改一下默认值,避免造成一些问题,最终的代码如下
  1. <script setup lang="ts">
  2. import { CountUp } from 'countup.js'
  3. import type { CountUpOptions } from 'countup.js'
  4. import { onMounted, ref } from 'vue'
  5. let numAnim = ref(null) as any
  6. const countupRef = ref()
  7. const props = defineProps({
  8. end: {
  9. type: Number,
  10. default: 0
  11. },
  12. options: {
  13. type: Object,
  14. validator(option: Object) {
  15. let keys = ['startVal', 'decimalPlaces', 'duration', 'useGrouping', 'useEasing', 'smartEasingThreshold', 'smartEasingAmount', 'separator', 'decimal', 'prefix', 'suffix', 'numerals']
  16. for (const key in option) {
  17. if (!keys.includes(key)) {
  18. console.error(" CountUp 传入的 options 值不符合 CountUpOptions")
  19. return false
  20. }
  21. }
  22. return true
  23. },
  24. default() {
  25. let options: CountUpOptions = {
  26. startVal: 0, // 开始的数字 一般设置0开始
  27. decimalPlaces: 2, // number类型 小数位,整数自动添.00
  28. duration: 2, // number类型 动画延迟秒数,默认值是2
  29. useGrouping: true, // boolean类型 是否开启逗号,默认true(1,000)false(1000)
  30. useEasing: true, // booleanl类型 动画缓动效果(ease),默认true
  31. smartEasingThreshold: 500, // numberl类型 大于这个数值的值开启平滑缓动
  32. smartEasingAmount: 300, // numberl类型
  33. separator: ',',// string 类型 分割用的符号
  34. decimal: '.', // string 类型 小数分割符合
  35. prefix: '', // sttring 类型 数字开头添加固定字符
  36. suffix: '', // sttring类型 数字末尾添加固定字符
  37. numerals: [] // Array类型 替换从0到9对应的字,也就是自定数字字符了,数组存储
  38. }
  39. return options
  40. }
  41. }
  42. })
  43. onMounted(() => {
  44. initCount()
  45. })
  46. const initCount = () => {
  47. numAnim = new CountUp(countupRef.value, props.end, props.options)
  48. numAnim.start()
  49. }
  50. defineExpose({
  51. initCount
  52. })
  53. </script>
  54. <template>
  55. <span ref="countupRef"></span>
  56. </template>
  57. <style scoped lang='scss'></style>

以上就是Vue3基于countUp.js怎么实现数字滚动的插件的详细内容,更多关于Vue3基于countUp.js怎么实现数字滚动的插件的资料请关注九品源码其它相关文章!