CountUp.js는 숫자 데이터를 보다 흥미로운 방식으로 표시하는 애니메이션을 빠르게 만드는 데 사용할 수 있는 종속성이 없는 가벼운 JavaScript 클래스입니다. CountUp은 전달된 시작 값과 끝 값에 따라 양방향으로 카운트할 수 있습니다.
countUp.js 보조 캡슐화를 기반으로 한 Vue 구성 요소가 시중에 많이 나와 있지만, 저는 개인적으로 이러한 타사 캡슐화를 사용하는 것을 좋아하지 않습니다. 왜냐하면 타사 구성 요소의 업데이트 빈도를 보장하기 어렵기 때문일 수도 있습니다. 그냥 변덕스럽게 캡슐화한 것 뿐이고 계속해서 유지할 생각은 없습니다. 만약 사용한다면 앞으로도 전혀 유지보수가 불가능하다는 의미이므로 이차 캡슐화를 구현하는 것을 추천합니다. 우리는 vue3
, ts
구문vue3
, ts
的语法
首先进行安装
npm i countup.js
安装好之后新建文件 CountUp.vue
, template部分很简单, 只需要一个span
标签, 同时给span
一个 ref='countupRef'
就完成了,首先引入 countup.js
, 按住Ctrl鼠标左键点击Countup.js可以看到 d.ts文件, countUp.d.ts
如下
export interface CountUpOptions { startVal?: number; decimalPlaces?: number; duration?: number; useGrouping?: boolean; useIndianSeparators?: boolean; useEasing?: boolean; smartEasingThreshold?: number; smartEasingAmount?: number; separator?: string; decimal?: string; easingFn?: (t: number, b: number, c: number, d: number) => number; formattingFn?: (n: number) => string; prefix?: string; suffix?: string; numerals?: string[]; enableScrollSpy?: boolean; scrollSpyDelay?: number; scrollSpyOnce?: boolean; onCompleteCallback?: () => any; plugin?: CountUpPlugin; } export declare interface CountUpPlugin { render(elem: HTMLElement, formatted: string): void; } export declare class CountUp { private endVal; options?: CountUpOptions; version: string; private defaults; private rAF; private startTime; private remaining; private finalEndVal; private useEasing; private countDown; el: HTMLElement | HTMLInputElement; formattingFn: (num: number) => string; easingFn?: (t: number, b: number, c: number, d: number) => number; error: string; startVal: number; duration: number; paused: boolean; frameVal: number; once: boolean; constructor(target: string | HTMLElement | HTMLInputElement, endVal: number, options?: CountUpOptions); handleScroll(self: CountUp): void; /** * Smart easing works by breaking the animation into 2 parts, the second part being the * smartEasingAmount and first part being the total amount minus the smartEasingAmount. It works * by disabling easing for the first part and enabling it on the second part. It is used if * usingEasing is true and the total animation amount exceeds the smartEasingThreshold. */ private determineDirectionAndSmartEasing; start(callback?: (args?: any) => any): void; pauseResume(): void; reset(): void; update(newEndVal: string | number): void; count: (timestamp: number) => void; printValue(val: number): void; ensureNumber(n: any): boolean; validateValue(value: string | number): number; private resetDuration; formatNumber: (num: number) => string; easeOutExpo: (t: number, b: number, c: number, d: number) => number; }
这里 export 了一个 CountUp
类 还有一个 CountUpOptions
的interface, CountUp
类的 constructor
接收三个参数, 分别是 dom节点, endVal, 以及 options, 我们将这三个参数当成是 props
传入同时给定默认值, , 首先获取span的ref作为 countUp
初始化的容器 , 定义一个变量 numAnim
接收 new CountUp(countupRef.value, props.end, props.options)
的返回值, , 在 onMounted
中初始化countUp.js
,接着我们就可以去页面引入 CountUp.vue
看看效果,因为有默认值,所以我们不需要传入任何参数, 直接看就好了, 此时CountUp.vue
组件代码如下,
<script setup lang="ts"> import { CountUp } from 'countup.js' import type { CountUpOptions } from 'countup.js' import { onMounted, ref } from 'vue' let numAnim = ref(null) as any const countupRef = ref() const props = defineProps({ end: { type: Number, default: 2023 }, options: { type: Object, default() { let options: CountUpOptions = { startVal: 0, // 开始的数字 一般设置0开始 decimalPlaces: 2, // number类型 小数位,整数自动添.00 duration: 2, // number类型 动画延迟秒数,默认值是2 useGrouping: true, // boolean类型 是否开启逗号,默认true(1,000)false(1000) useEasing: true, // booleanl类型 动画缓动效果(ease),默认true smartEasingThreshold: 500, // numberl类型 大于这个数值的值开启平滑缓动 smartEasingAmount: 300, // numberl类型 separator: ',',// string 类型 分割用的符号 decimal: '.', // string 类型 小数分割符合 prefix: '¥', // sttring 类型 数字开头添加固定字符 suffix: '元', // sttring类型 数字末尾添加固定字符 numerals: [] // Array类型 替换从0到9对应的字,也就是自定数字字符了,数组存储 } return options } } }) onMounted(() => { initCount() }) const initCount = () => { numAnim = new CountUp(countupRef.value, props.end, props.options) numAnim.start() } </script> <template> <span ref="countupRef"></span> </template>
这时我们发现,在 onMounted
执行之后, 如果我们的endVal值发生了改动, 由于 CountUp.vue
的 onMounted
已经完成,并不会同步修改, 如果我们的值是异步获取的,会造成渲染不出我们想要的结果,那么我们就需要在组件中把这个 initCount
方法给暴露给父组件使用,在vue3中,我们只需要使用 defineExpose
暴露即可, 同时我们也进一步完善一下我们的props, 校验限制一下传入的optinos
<script setup lang="ts"> import { CountUp } from 'countup.js' import type { CountUpOptions } from 'countup.js' import { onMounted, ref } from 'vue' let numAnim = ref(null) as any const countupRef = ref() const props = defineProps({ end: { type: Number, default: 0 }, options: { type: Object, validator(option: Object) { let keys = ['startVal', 'decimalPlaces', 'duration', 'useGrouping', 'useEasing', 'smartEasingThreshold', 'smartEasingAmount', 'separator', 'decimal', 'prefix', 'suffix', 'numerals'] for (const key in option) { if (!keys.includes(key)) { console.error(" CountUp 传入的 options 值不符合 CountUpOptions") return false } } return true }, default() { let options: CountUpOptions = { startVal: 0, // 开始的数字 一般设置0开始 decimalPlaces: 2, // number类型 小数位,整数自动添.00 duration: 2, // number类型 动画延迟秒数,默认值是2 useGrouping: true, // boolean类型 是否开启逗号,默认true(1,000)false(1000) useEasing: true, // booleanl类型 动画缓动效果(ease),默认true smartEasingThreshold: 500, // numberl类型 大于这个数值的值开启平滑缓动 smartEasingAmount: 300, // numberl类型 separator: ',',// string 类型 分割用的符号 decimal: '.', // string 类型 小数分割符合 prefix: '', // sttring 类型 数字开头添加固定字符 suffix: '', // sttring类型 数字末尾添加固定字符 numerals: [] // Array类型 替换从0到9对应的字,也就是自定数字字符了,数组存储 } return options } } }) onMounted(() => { initCount() }) const initCount = () => { numAnim = new CountUp(countupRef.value, props.end, props.options) numAnim.start() } defineExpose({ initCount }) </script> <template> <span ref="countupRef"></span> </template> <style scoped lang='scss'></style>
CountUp.vue를 생성합니다.
. 템플릿 부분은 매우 간단합니다. span
태그가 하나만 있고 완료하려면 span
에 ref='countupRef'
를 제공하세요. 먼저 countup.js
를 소개하고 Ctrl 왼쪽 마우스 버튼을 누른 채 Countup.js를 클릭하면 다음과 같이 d.ts 파일인 countUp.d.ts
를 볼 수 있습니다🎜rrreee🎜 여기에서 CountUp
클래스와 CountUpOptions
인터페이스를 내보냈습니다. CountUp
클래스의 생성자
는 dom 노드라는 세 가지 매개변수를 받습니다. endVal 및 options. 이 세 가지 매개변수는 props
가 전달되고 기본값이 제공되는 것으로 간주됩니다. 먼저 countUp
초기화를 위한 컨테이너로 범위의 참조를 가져옵니다. numAnim
변수를 정의하고 새 CountUp(countupRef.value, props.end, props.options의 반환 값)
을 수신하고 countUp.js
를 초기화합니다. > onMounted
에서 이를 CountUp.vue
페이지로 가져올 수 있습니다. 효과를 살펴보세요. 기본값이 있으므로 그럴 필요가 없습니다. 아무 매개변수나 전달하면 됩니다. 이때 CountUp.vue
구성 요소 코드는 다음과 같습니다. 🎜rrreee🎜 이때 onMounted
뒤에 있는 것을 발견했습니다. 실행 시, CountUp.vue
의 onMounted
가 완료되었기 때문에 endVal 값이 변경되면 값이 비동기적으로 얻어지는 경우 결과는 동기식으로 수정되지 않습니다. 원하는 항목은 렌더링되지 않으므로 이 initCount
메서드를 구성 요소의 상위 항목에 노출해야 합니다. vue3에서는 defineExpose
를 사용하여 노출하기만 하면 됩니다. 동시에 props를 더욱 개선하고 수신되는 optinos
값을 확인하고 제한합니다. 사용 오류를 방지하고 일부 문제가 발생하지 않도록 기본값을 수정합니다. 다음과 같습니다 🎜rrreee위 내용은 countUp.js를 기반으로 Vue3에서 디지털 스크롤 플러그인을 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!