VueUse函数库介绍

一、是什么

Vue3引入的组合式API 带来了新的复用逻辑的方式,我们可以把重复的有状态的逻辑抽取成函数,供页面调用,而且这些函数还能被组合使用,更加灵活。

VueUse就是这样一个基于组合式API的函数库,封装了很多常见的,可复用的函数,支持Vue2,Vue3,Nuxt,可以理解为Vue世界的lodash,开箱即用,非常方便。

二、现状

作者:AnthonyFu,Vue、Vite团队核心成员

官网:vueuse.org/

中文地址:www.vueusejs.com/

Github:github.com/vueuse/vueu...

注: 官网最新版本V10.7.2;中文地址非官方,保留了官方英文网站的原文,翻译文档最新版本V9.13.0。Github仓库Start 17.9k,更新频繁,非常活跃。

三、功能

核心包有140+组合式函数,此外还提供了10个扩展插件,共约有290+函数

核心包中提供了12种类型的函数,如下所示:

State:管理用户状态(如:全局、本地存储、会话存储)

Elements:元素处理相关(如:元素拖拽、元素可见性、窗口尺寸)

Browser:浏览器相关(如:更新页面title、媒体查询、剪贴板)

Sensors:监听不同的DOM事件、输入事件和网络事件等

Network:网络请求相关

Animation:过渡、超时和计时功能

Component:提供了不同组件方法的简写

Watch:提供一些监听器(如:监听promise后的变化、防抖监听、节流监听)

Reactivity:响应式函数相关

Array:响应式的数组处理

Time:提供响应时间格式化功能

Utilities:通用函数,如 节流、防抖等

扩展插件:Electron、Firebase、Head、Integrations、Math、Motion、Router、RxJS、SchemaOrg、Sound

核心功能都在packages/core文件夹下。

四、使用

  1. 安装
js 复制代码
  // npm、yarn、pnpm 都可以,安装核心包 @vueuse/core

  npm i @vueuse/core

  yarn add @vueuse/core

  pnpm add @vueuse/core 
  1. 使用

作为函数直接调用:比如 const { toggle } = useFullScreen(),这也是我们最常用的方式。

作为组件使用 :部分功能提供,比如<UseFullscreen><UseFullscreen>

作为函数直接调用时,可以接收响应式参数 ,大多数函数都会返回一个refs对象,可以使用对象解构来获取需要的内容。函数通常以use开头。

VueUse提供了如上两种使用方法,下面分享两个常用的函数useFullscreen、useStorage来详细说明。

  • useFullscreen

封装了全屏相关的功能, 功能文档:vueuse.org/core/useful...

函数式调用方法:

html 复制代码
  <span @click="toggle">
      <VbenSvgIcon :size="18" icon="fullscreen" v-if="!isFullscreen" />
      <VbenSvgIcon :size="18" icon="notfullscreen" v-else />
  </span>
js 复制代码
  import { useFullscreen } from '@vueuse/core'
  const { toggle, isFullscreen } = useFullscreen()

这是对整个页面全屏,除此之外还支持传入某个元素,这样只会对该元素区域进行全屏显示,如下:

html 复制代码
 <div>
    isFullscreen: {{ isFullscreen }}
    <button @click="toggle">开启全屏</button>
    <div ref="el" style="background: yellow;">把我全屏</div>
  </div>
js 复制代码
  import { useFullscreen } from '@vueuse/core'
  const el = ref<HTMLElement | null>(null)
  const { isFullscreen, toggle } = useFullscreen(el)

组件式用法, 除了安装@vueuse/core核心包之外,还需要安装 @vueuse/components,即

js 复制代码
pnpm add @vueuse/core  @vueuse/components
html 复制代码
    <UseFullscreen v-slot="{ toggle }">
      <button @click="toggle">
        Go Fullscreen
      </button>
    </UseFullscreen>
js 复制代码
 import { UseFullscreen } from '@vueuse/components'

源码

源码位置:packages/core/useFullscreen

有四个文件:component.ts、demo.vue、index.md、index.ts

component.ts:封装函数的无渲染组件,所以我们能以组件的方式调用

demo.vue:示例

index.md:说明文件

index.ts:核心代码(100+行)

函数声明:

js 复制代码
export declare function useFullscreen(
    target?: MaybeElementRef,
    options?: UseFullscreenOptions,
): {
    isSupported: ComputedRef<boolean>
    isFullscreen: Ref<boolean>
    enter: () => Promise<void>
    exit: () => Promise<void>
    toggle: () => Promise<void>
}

核心源码:

js 复制代码
export function useFullscreen(
  target?: MaybeElementRef,
  options: UseFullscreenOptions = {},

) {
  // ...
  const targetRef = computed(() => unrefElement(target) ?? document?.querySelector('html'))
  const isFullscreen = ref(false)

  // 可以学习这种写法 
  const requestMethod = computed<'requestFullscreen' | undefined>(() => {
    return [
      'requestFullscreen',
      'webkitRequestFullscreen',
      'webkitEnterFullscreen',
      'webkitEnterFullScreen',
      'webkitRequestFullScreen',
      'mozRequestFullScreen',
      'msRequestFullscreen',
    ].find(m => (document && m in document) || (targetRef.value && m in targetRef.value)) as any
  })
  // ...
 
  async function exit() {
    if (!isSupported.value || !isFullscreen.value)
      return
    if (exitMethod.value) {
      if (document?.[exitMethod.value] != null) {
        await document[exitMethod.value]()
      }
      else {
        const target = targetRef.value
        // @ts-expect-error - Fallback for Safari iOS
        if (target?.[exitMethod.value] != null)
          // @ts-expect-error - Fallback for Safari iOS
          await target[exitMethod.value]()
      }
    }
    isFullscreen.value = false
  }

  async function enter() {
    if (!isSupported.value || isFullscreen.value)
      return
    if (isElementFullScreen())
      await exit()
    const target = targetRef.value
    if (requestMethod.value && target?.[requestMethod.value] != null) {
      await target[requestMethod.value]()
      isFullscreen.value = true
    }
  }

  async function toggle() {
    await (isFullscreen.value ? exit() : enter())
  }

  return {
    isSupported,
    isFullscreen,
    enter,
    exit,
    toggle,
  }
}
  • useStorage

VueUse里面封装的useStorage有很多优点,易于使用。useLocalStorage和useSessionStorage内部直接调用的useStorage,默认存储方式为localStorage和sessionStorage。

  1. 使用useStorage会直接返回一个响应式ref,直接改变ref的值,本地存储也会同步更新。

2.保存数据数据时也没有限制只能是string类型,支持多种类型,如对象、布尔、数字等。

3.可以直接更改对象的某个字段,不需要像用原生API一样整体替换。

4.内部监听了storage事件,所以直接面板操作,也能响应式更新。

html 复制代码
<div>
    storage: {{ state }}
    <button @click="edit">修改</button>
    <button @click="clear">清除</button>
  </div>
js 复制代码
import { useStorage } from '@vueuse/core'
  // 不限制存储值的类型
  const state = useStorage('liufeifei-test',  [1,2,3])
  // 返回一个ref
  console.log('state', state)
  const edit = () => {
    // 可以直接更新对象字段
    state.value[1] = 222 
  }

  const clear = () => {
    state.value = null
  }

调用useStore返回一个ref

localStorage存储成功

js 复制代码
  import { useStorage } from '@vueuse/core'
  
  // 如果存储的字段已经有值,不会被更新
  localStorage.setItem('liufeifei-test', '{ "a": 1 }')
  const state = useStorage('liufeifei-test', { a: 111, b: 222 })
  console.log('state', state.value) // Proxy {a : 1}
  
  // 可以通过配置 mergeDefaults: true; 合并值
  const state1 = useStorage('liufeifei-test', { a: 111, b: 222 }, localStorage, { mergeDefaults: true })
  console.log('state1', state1.value) // Proxy { a : 1, b: 222 }

源码

源码位置:packages/core/useStorage ( 核心代码200+行)

五、其他

VueUse封装了非常多实用功能,如:剪切板(useClipboard)、防抖(useDebounceFn), 设置网页的title(useTitle),监听事件(useEventListener, 页面卸载可以自动帮助我们删除事件监听,不用我们手动删除)等等,自己封装hooks前,可以去官网看看有没有已经封装好的,提升开发效率。

VueUse还有很好的交互文档和功能演示 ,TS编写,每个功能的核心源码也都比较少,比较好读,除了可以使用其封装的功能外,我们还可以看其源码学习功能封装技巧,学习优秀的编码习惯。

相关推荐
musk12121 分钟前
electron 打包太大 试试 tauri , tauri 安装打包demo
前端·electron·tauri
翻滚吧键盘30 分钟前
js代码09
开发语言·javascript·ecmascript
万少1 小时前
第五款 HarmonyOS 上架作品 奇趣故事匣 来了
前端·harmonyos·客户端
OpenGL1 小时前
Android targetSdkVersion升级至35(Android15)相关问题
前端
rzl021 小时前
java web5(黑马)
java·开发语言·前端
Amy.Wang1 小时前
前端如何实现电子签名
前端·javascript·html5
海天胜景1 小时前
vue3 el-table 行筛选 设置为单选
javascript·vue.js·elementui
今天又在摸鱼1 小时前
Vue3-组件化-Vue核心思想之一
前端·javascript·vue.js
蓝婷儿1 小时前
每天一个前端小知识 Day 21 - 浏览器兼容性与 Polyfill 策略
前端
百锦再1 小时前
Vue中对象赋值问题:对象引用被保留,仅部分属性被覆盖
前端·javascript·vue.js·vue·web·reactive·ref