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编写,每个功能的核心源码也都比较少,比较好读,除了可以使用其封装的功能外,我们还可以看其源码学习功能封装技巧,学习优秀的编码习惯。

相关推荐
minDuck1 分钟前
ruoyi-vue集成tianai-captcha验证码
java·前端·vue.js
小政爱学习!22 分钟前
封装axios、环境变量、api解耦、解决跨域、全局组件注入
开发语言·前端·javascript
魏大帅。27 分钟前
Axios 的 responseType 属性详解及 Blob 与 ArrayBuffer 解析
前端·javascript·ajax
花花鱼33 分钟前
vue3 基于element-plus进行的一个可拖动改变导航与内容区域大小的简单方法
前端·javascript·elementui
k093337 分钟前
sourceTree回滚版本到某次提交
开发语言·前端·javascript
EricWang13581 小时前
[OS] 项目三-2-proc.c: exit(int status)
服务器·c语言·前端
September_ning1 小时前
React.lazy() 懒加载
前端·react.js·前端框架
web行路人1 小时前
React中类组件和函数组件的理解和区别
前端·javascript·react.js·前端框架
番茄小酱0011 小时前
Expo|ReactNative 中实现扫描二维码功能
javascript·react native·react.js
子非鱼9211 小时前
【Ajax】跨域
javascript·ajax·cors·jsonp