useCounter - VueUse 源码解读

107 阅读1分钟

1、作用

具有实用功能的基本计数器;

2、例子

2.1 基础用法

import { useCounter } from '@vueuse/core'

const { count, inc, dec, set, reset } = useCounter()

2.2 含参数的用法

import { useCounter } from '@vueuse/core'

const { count, inc, dec, set, reset } = useCounter(1, { min: 0, max: 16 })

2.3 结合实际场景 - 包裹数量 (推荐写法)

<script setup lang="ts">
import { reactive } from 'vue-demi'
import { useCounter } from '@vueuse/core'

const packageNum = reactive(useCounter(1, { min: 1, max: 10 }))

</script>

<template>
  <div>
    <p>Count: {{ packageNum.count }}</p>
    <div>
      <button @click="packageNum.inc()">
        Increment
      </button>
      <button @click="packageNum.dec()">
        Decrement
      </button>
      <button @click="packageNum.inc(5)">
        Increment (+5)
      </button>
      <button @click="packageNum.dec(5)">
        Decrement (-5)
      </button>
      <button @click="packageNum.set(100)">
        Set (100)
      </button>
      <button @click="packageNum.reset()">
        Reset
      </button>
    </div>
  </div>
</template>


3、源码解读

这是一个很标准的组合式函数的范式,正在学习如何使用组合式api的同学可以借鉴这个思维;将数据和改变这个数据的逻辑(方法)封装在一个use中,这样子在使用时,无需关注其内部逻辑,并且可以将逻辑内聚在一起,这样子代码才更有条理,也具备可复用性。

// eslint-disable-next-line no-restricted-imports
import { ref, unref } from 'vue-demi'
import type { MaybeRef } from '../utils'

export interface UseCounterOptions {
  min?: number
  max?: number
}

/**
 * Basic counter with utility functions.
 *
 * @see https://vueuse.org/useCounter
 * @param [initialValue]
 * @param options
 */
export function useCounter(initialValue: MaybeRef<number> = 0, options: UseCounterOptions = {}) {
  let _initialValue = unref(initialValue)
  const count = ref(initialValue)

  const {
    max = Number.POSITIVE_INFINITY,
    min = Number.NEGATIVE_INFINITY,
  } = options

  const inc = (delta = 1) => count.value = Math.max(Math.min(max, count.value + delta), min)
  const dec = (delta = 1) => count.value = Math.min(Math.max(min, count.value - delta), max)
  const get = () => count.value
  const set = (val: number) => (count.value = Math.max(min, Math.min(max, val)))
  const reset = (val = _initialValue) => {
    _initialValue = val
    return set(val)
  }

  return { count, inc, dec, get, set, reset }
}