Heim  >  Artikel  >  Web-Frontend  >  So implementieren Sie ein Plug-in für digitales Scrollen in Vue3 basierend auf countUp.js

So implementieren Sie ein Plug-in für digitales Scrollen in Vue3 basierend auf countUp.js

WBOY
WBOYnach vorne
2023-05-10 22:19:041919Durchsuche

countUp Einführung

CountUp.js ist eine leichte, abhängigkeitsfreie JavaScript-Klasse, mit der schnell Animationen erstellt werden können, die numerische Daten auf interessantere Weise darstellen. CountUp kann abhängig von den übergebenen Start- und Endwerten in beide Richtungen zählen.

Obwohl es viele Vue-Komponenten auf dem Markt gibt, die auf der sekundären Kapselung von countUp.js basieren, verwende ich persönlich diese Kapselungen von Drittanbietern nicht gern, da es schwierig ist, die Aktualisierungshäufigkeit von Drittanbietern zu garantieren. Party-Komponenten. Vielleicht hat der Autor es nur aus einer Laune heraus gekapselt und hochgeladen und wollte es nicht weiter pflegen. Wenn es verwendet wird, bedeutet dies, dass es in Zukunft überhaupt nicht mehr wartbar ist Sie können die Syntax von vue3ts selbst kennen lernen #Erste Installation vue3, ts 的语法

countUp 组件封装

首先进行安装

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 &#39;countup.js&#39;
  import type { CountUpOptions } from &#39;countup.js&#39;
  import { onMounted, ref } from &#39;vue&#39;

  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: &#39;,&#39;,// string 类型 分割用的符号
          decimal: &#39;.&#39;, // string 类型  小数分割符合
          prefix: &#39;¥&#39;, // sttring 类型  数字开头添加固定字符
          suffix: &#39;元&#39;, // 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.vueonMounted 已经完成,并不会同步修改, 如果我们的值是异步获取的,会造成渲染不出我们想要的结果,那么我们就需要在组件中把这个 initCount 方法给暴露给父组件使用,在vue3中,我们只需要使用 defineExpose 暴露即可, 同时我们也进一步完善一下我们的props, 校验限制一下传入的optinos

<script setup lang="ts">
  import { CountUp } from &#39;countup.js&#39;
  import type { CountUpOptions } from &#39;countup.js&#39;
  import { onMounted, ref } from &#39;vue&#39;

  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 = [&#39;startVal&#39;, &#39;decimalPlaces&#39;, &#39;duration&#39;, &#39;useGrouping&#39;, &#39;useEasing&#39;, &#39;smartEasingThreshold&#39;, &#39;smartEasingAmount&#39;, &#39;separator&#39;, &#39;decimal&#39;, &#39;prefix&#39;, &#39;suffix&#39;, &#39;numerals&#39;]
        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: &#39;,&#39;,// string 类型 分割用的符号
          decimal: &#39;.&#39;, // string 类型  小数分割符合
          prefix: &#39;&#39;, // sttring 类型  数字开头添加固定字符
          suffix: &#39;&#39;, // 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=&#39;scss&#39;></style>

Erstellen Sie nach der Installation eine neue Datei CountUp.vue. Der Vorlagenteil ist sehr einfach, es ist nur ein span-Tag erforderlich , und geben Sie span einen ref='countupRef' code> ein. Führen Sie zunächst <code>countup.js ein, halten Sie die Strg-Taste gedrückt und klicken Sie mit der linken Maustaste auf Countup.js Um die d.ts-Datei anzuzeigen, lautet countUp.d.ts wie folgt #🎜🎜#rrreee#🎜🎜#Hier wurde eine CountUp-Klasse und eine Schnittstelle von CountUpOptions und der Konstruktor der <code>CountUp-Klasse empfangen drei Parameter, nämlich dom node, endVal und Optionen. Wir behandeln diese drei Parameter als props und übergeben Sie sie unter Angabe eines Standardwerts. Rufen Sie zunächst die Referenz von span als countUp initialisierten Container ab und definieren Sie eine Variable numAnim, um den Rückgabewert zu erhalten von new CountUp(countupRef.value, props.end, props.options), , countUp.js in onMounted initialisieren, dann kann es losgehen Gehen Sie auf die Seite, um CountUp.vue einzuführen, um den Effekt zu sehen, da es einen Standardwert gibt. Wir müssen also keine Parameter übergeben, schauen Sie sich das einfach direkt an Der CountUp.vue-Komponentencode lautet wie folgt: #🎜🎜#rrreee#🎜🎜#Zu diesem Zeitpunkt haben wir festgestellt, dass in onMounted Nach der Ausführung, wenn sich unser endVal-Wert ändert, seitdem <code>CountUp.vues onMounted wurde nicht synchron geändert. Wenn unser Wert asynchron ist, führt dies dazu, dass das gewünschte Ergebnis nicht gerendert wird. Dann müssen wir diese initCount-Methode in der Komponente für die übergeordnete Komponente verfügbar machen. In vue3 müssen wir nur defineExpose verwenden Verbessern Sie unsere Requisiten weiter, überprüfen und begrenzen Sie den eingehenden optinos-Wert, versuchen Sie, Verwendungsfehler zu vermeiden, und ändern Sie den Standardwert, um einige Probleme zu vermeiden. Der endgültige Code lautet wie folgt #🎜🎜#rrreee

Das obige ist der detaillierte Inhalt vonSo implementieren Sie ein Plug-in für digitales Scrollen in Vue3 basierend auf countUp.js. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen