useToggle - VueUse 源码解读

221 阅读1分钟

1、作用

支持自定义真假值的切换器

2、使用案例

<script setup lang='ts'>
import { useToggle } from '@/hooks'

// 用法1
const [ isOn, toggle ] = useToggle() // 返回的是个数组,方便解构重新命名变量

// 用法2
// const [ spread, toggle ] = useToggle('展开', {
//   truthyValue: '展开',
//   falsyValue: '收起',
// })

// 用法3
// const isLate = ref(false)
// const toggle = useToggle(isLate)

</script>

<template>
  <div>当前:{{ isOn }}</div>
  <!-- 注意:请注意,toggle函数接受第一个参数作为覆盖值。您可能希望避免直接将函数传递给模板中的事件,因为事件对象将传入 -->
  <button @click="toggle()">切换</button>
  <!-- 不应该使用: <button @click="toggle">切换</button> -->
  <button @click="toggle(true)"></button>
  <button @click="toggle(false)"></button>
</template>
<style  scoped>
</style>

3、源码解读

1、正值、假值的ts定义值得借鉴学习 2、返回的是个数组,方便解构重新命名变量

import type { Ref } from 'vue'
import { MaybeRefOrGetter, MaybeRef } from '../utils'
import { isRef, ref } from 'vue'
import { toValue } from '../toValue'

export interface UseToggleOptions<Truthy, Falsy> {
  truthyValue?: MaybeRefOrGetter<Truthy>
  falsyValue?: MaybeRefOrGetter<Falsy>
}

// 重载1,初始值是ref,返回值是切换该值的函数
export function useToggle<Truthy, Falsy, T = Truthy | Falsy>(initialValue: Ref<T>, options?: UseToggleOptions<Truthy, Falsy>): (value : T) => T
// 重载2,初始值为不传,或者是泛型,返回值是ref和切换该ref的函数
export function useToggle<Truthy = true, Falsy = false, T = Truthy | Falsy>(initialValue?: T, options?: UseToggleOptions<Truthy, Falsy>): [Ref<T>, (value?: T) => T]

export function useToggle(
    initialValue: MaybeRef<boolean> = false,
    options: UseToggleOptions<true, false> = {},
) {
    const {
      truthyValue = true,
      falsyValue = false,
    } = options
    // 初始值是ref
    const valueIsRef = isRef(initialValue)
    const _value = ref(initialValue) as Ref<boolean>

    function toggle(value?: boolean) {
        if (arguments.length) {
          _value.value = value!
          return _value.value
        }
        else {
          const truthy = toValue(truthyValue)
          _value.value = _value.value === truthy
            ? toValue(falsyValue)
            : truthy
          return _value.value
        }
      }

    if (valueIsRef) {
        return toggle
    } else {
        return [_value, toggle] as const
    }
}