手摸手带你封装一个 vue 3『计数动画』组件


欢迎关注我的公众号『 前端我废了 』,查看更多文章!!!
​​​在这里插入图片描述

前言

在我们做一些数据可视化项目时,数字计数动画是一个很常见的需求,本文我们借助 countup.js 插件来实现效果,将它封装成一个 vue 3 组件,并扩展一些功能。

countup.js 介绍

countup.js 是一个可以快速创建各种有趣的数值动画效果的插件。例如可以自定义动画过渡函数,千分位符号,小数点位数,数值前后缀符号,数字符号替换等等。

它的构造函数有以下三个参数:

  • target html 元素 id 或者 DOM 对象
  • endVal 结束值
  • options 其他可选配置项
constructor(target: string | HTMLElement | HTMLInputElement, endVal: number, options?: CountUpOptions)

它的 options 有以下可选配置项:

interface CountUpOptions {
  startVal?: number // 开始数值,默认 0
  decimalPlaces?: number // 小数点后位数,默认 0
  duration?: number // 动画时长,默认 2s
  prefix?: string // 数值前缀
  suffix?: string // 数值后缀
  // ...其他配置项
}

示例

const countup = new CountUp('targetId', 5234, options)
// 调用 start 方法开始计数
countup.start()

封装组件

我们抽出 countup.js 的以下属性作为我们组件 prop,其余的配置项通过 options 属性暴露出来供外部配置。

  • endVal 开始数值
  • startVal 结束数值
  • duration 动画时长,单位:秒
// 简略代码,完整代码可查看仓库
<script setup lang="ts">
defineProps<{
  endVal: number | string
  startVal?: number | string
  duration?: number | string
  options?: CountUpOptions
}>()

let elRef = ref<HTMLElement>()
onMounted(() => {
  new CountUp()
})
</script>

使用组件

 <count-up :end-val="2000"></count-up>

以上,就完成了对 countup.js 插件的简单封装。下面我们将在这基础上扩展一些功能。

扩展功能

我们想要给组件增加以下功能:

  • 自动计数:组件渲染后自动计数
  • 循环计数:支持无限\有限次循环
  • 前后缀插槽:满足自定义前后缀需求
1. 自动计数

countup.js 每次创建实例后需要我们手动调用 start() 方法来启动计数。我们给组件添加一个 autoplay 属性,来让组件渲染后默认自动计数。

// 简略代码,完整代码可查看仓库
<script setup lang="ts">
const props = defineProps({
  autoplay: {
    type: Boolean,
    default: true
  }
})
// 在 onMounted 判断一下就 ok 了
onMounted(() => {
  if(props.autoplay) {
    countup.start()
  }
})
</script>
2. 循环计数

首先,定义一个循环函数 loopAnim
实现无限次循环countup.jsstart(callback) 方法支持传入一个回调函数,会在计数完成时执行,因此我们只需要在回调内继续调用 loopAnim() 函数就可以实现无限循环;
实现有限次循环:定义一个变量 loopCount 记录循环的次数,当小于我们定义的次数时,继续调用 loopAnim

// 简略代码,完整代码可查看仓库
<script setup lang="ts">
const props = defineProps({
  // 支持传入布尔值或循环次数数值
  loop: {
    type: [Boolean, Number],
    default: false
  }
})
let loopCount = 0
const loopAnim = () => {
  loopCount++
  // 判断是否为布尔值且为 true
  const isTruely = typeof props.loop === 'boolean'
                    && props.loop
  // 当为 true 或者已循环次数小于我们定义的次数时,继续循环计数
  if(isTruely || props.loop > loopCount) {
    countup.start(loopAnim)
  }
}
onMounted(() => {
  countup.start(loopAnim)
})
</script>
3. 前后缀插槽

当我们需要区分开前后缀与数字的样式时,可以通过插槽的形式实现,这个比较简单,只需要在组件 template 内定义两个具名插槽即可。

<template>
  <div class="countup-wrap">
    // 前缀插槽
    <slot name="prefix"></slot>
    // 数值显示位置
    <span ref="elRef"> </span>
    // 后缀插槽
    <slot name="suffix"></slot>
  </div>
</template>

总结

        ok,到这里我们已经通过将 countup.js 封装为 vue 组件,实现满足了我们的需求,详细的代码实现可以查看我的 github 仓库。
        我们后续可以把这个组件发布到 npm 上面,方便使用的同时也可以让更多人来使用你的组件,具体步骤可以自己看看其他文章怎么发布到 npm 上。

相关地址

npm
https://www.npmjs.com/package/vue-countup-v3

github
https://github.com/jizai1125/vue-countup-v3

在线 demo
https://jizai1125.github.io/vue-countup-v3/examples/

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值