VueUse 是基于 Vue3 Composition API 开发的实用函数集合库,由 Vue 核心团队成员主导维护,收录了200+开箱即用的工具函数,覆盖 DOM 操作、浏览器 API、响应式状态管理、性能优化等几乎所有前端开发场景。其核心理念是"拒绝重复造轮子",将开发中常用但繁琐的逻辑(如本地存储、鼠标监听、防抖节流)封装成可复用的组合式函数,让开发者专注于业务逻辑,大幅提升开发效率。
VueUse 完美适配 Vue3,原生支持 TypeScript,支持摇树优化(Tree Shaking),按需引入不冗余,同时兼容 Vue2(需使用对应版本)和 SSR 场景,是 Vue3 项目开发的必备工具库之一。
一、VueUse 核心特点
- Composition API 原生适配:所有函数均基于 Vue3 setup 语法和 ref/reactive 构建,API 风格与 Vue3 原生语法高度一致,上手无压力,无需额外学习成本。
- 类型友好:全程使用 TypeScript 编写,自带完整类型定义,开发时可获得精准代码提示,减少类型错误,适配 TS 项目开发需求。
- 模块化设计:采用按需引入机制,仅打包用到的函数,避免引入全部模块造成的体积膨胀,优化项目打包性能。
- 场景覆盖广泛:涵盖响应式状态、浏览器能力、DOM 操作、表单控制、网络请求、性能优化等200+场景,满足日常开发99%的需求。
- 灵活通用:支持 CDN 引入(无需打包器),适配 Vite、Webpack、Nuxt 等多种构建工具,同时支持 SSR 友好,可搭配 Vue Router、Firebase 等插件使用。
- 中文文档完善:官方提供中文文档,每个函数均有交互式演示,查询便捷,新手可快速上手。
二、环境安装(Vue3 实战首选)
VueUse 核心包为 @vueuse/core,包含绝大多数常用工具函数;若需特定场景(如音频、地图),可安装对应子包。以下是主流安装方式,推荐使用 npm 或 pnpm:
2.1 核心包安装(必装)
java
// npm 安装(推荐,适配绝大多数项目)
npm install @vueuse/core -S
// yarn 安装
yarn add @vueuse/core
// pnpm 安装(高效包管理,推荐)
pnpm add @vueuse/core
2.2 特定场景子包安装(按需选择)
若需使用音频、地图、Firebase 等特定功能,可单独安装对应子包:
java
// 音频相关工具(如播放、录音)
npm install @vueuse/sound -S
// 地图相关工具(如高德、百度地图集成)
npm install @vueuse/map -S
// Firebase 集成工具
npm install @vueuse/firebase -S
2.3 CDN 引入(无需打包器,快速测试)
适合快速演示或无需打包的简单项目,引入后可通过 window.VueUse 访问所有函数:
xml
<script src="https://unpkg.com/@vueuse/shared"></script>
<script src="https://unpkg.com/@vueuse/core"></script>
2.4 Nuxt 项目适配
Nuxt 3 已内置 VueUse 支持,无需单独安装,仅需在配置文件中注册模块即可实现自动引入:
arduino
// nuxt.config.ts(Nuxt 3)
export default defineNuxtConfig({
modules: ['@vueuse/nuxt']
})
三、核心用法(按场景分类,实战必备)
VueUse 的使用逻辑简单统一:按需引入所需函数,在 setup 语法中调用,即可获得响应式结果或封装好的逻辑,无需手动处理事件绑定、销毁等冗余操作。以下按高频场景分类讲解,代码可直接复制套用。
3.1 响应式状态与本地存储(最常用)
用于处理响应式状态切换、计数器、本地存储(localStorage/sessionStorage)等场景,自动处理 JSON 序列化和响应式同步,刷新页面数据不丢失。
3.1.1 useLocalStorage(本地持久化存储)
替代原生 localStorage,返回响应式 ref 对象,修改后自动同步到本地存储,适合存储用户偏好、登录态等需要持久化的数据:
xml
<template>
<div>
<p>当前主题:{{ theme }}</p>
<button @click="theme = theme === 'light' ? 'dark' : 'light'">切换主题</button>
</div>
</template>
<script setup lang="ts">
// 按需引入
import { useLocalStorage } from '@vueuse/core'
// 第一个参数:localStorage 键名;第二个参数:默认值
const theme = useLocalStorage('app_theme', 'light')
// 修改值时,自动同步到 localStorage
// theme.value = 'dark'
</script>
3.1.2 useSessionStorage(会话级存储)
用法与 useLocalStorage 完全一致,区别在于数据存储在 sessionStorage 中,关闭页面后自动丢失,适合存储临时数据(如表单草稿):
php
import { useSessionStorage } from '@vueuse/core'
// 存储临时表单数据
const tempForm = useSessionStorage('temp_form', { username: '', password: '' })
3.1.3 useToggle(布尔值切换)
快速实现布尔值切换逻辑,适合弹窗显示/隐藏、开关状态等场景:
xml
<template>
<button @click="toggle">{{ isShow ? '隐藏' : '显示' }}弹窗</button>
<div v-if="isShow" class="modal">弹窗内容</div>
</template>
<script setup lang="ts">
import { useToggle } from '@vueuse/core'
// 接收默认值,返回 [状态值, 切换函数]
const [isShow, toggle] = useToggle(false)
// 也可自定义切换值(如切换主题字符串)
// const [theme, toggleTheme] = useToggle('light', ['light', 'dark'])
</script>
3.1.4 useCounter(计数器工具)
封装计数器逻辑,支持增减、重置、设置值等操作,适合数量选择、分页页码等场景:
xml
<template>
<div>
<button @click="dec()">-</button>
<span>{{ count }}</span>
<button @click="inc()">+</button>
<button @click="reset()">重置</button>
<button @click="set(10)">设为10</button>
</div>
</template>
<script setup lang="ts">
import { useCounter } from '@vueuse/core'
// 默认值为0,可指定初始值和范围(如 min:0, max:10)
const { count, inc, dec, reset, set } = useCounter(0, { min: 0, max: 10 })
</script>
3.2 浏览器能力封装(简化原生 API)
将浏览器原生 API(如鼠标监听、网络状态、窗口尺寸)封装为响应式函数,自动处理事件绑定与销毁,避免内存泄漏。
3.2.1 useMouse(鼠标位置监听)
实时获取鼠标坐标,支持限制监听范围(如某元素内),适合鼠标跟随、悬浮交互等场景:
xml
<template>
<div>
<p>鼠标位置:({{ x.toFixed(0) }}, {{ y.toFixed(0) }})</p>
<div
class="follow"
:style="{ left: `${x + 10}px`, top: `${y + 10}px` }"
></div>
</div>
</template>
<script setup lang="ts">
import { useMouse } from '@vueuse/core'
// 获取鼠标x、y坐标(响应式)
const { x, y } = useMouse()
// 限制监听范围(仅在id为container的元素内监听)
// const { x, y } = useMouse({ target: document.getElementById('container') })
</script>
<style scoped>
.follow {
position: fixed;
width: 10px;
height: 10px;
background: red;
border-radius: 50%;
}
</style>
3.2.2 useNetwork(网络状态监听)
监听用户网络连接状态(在线/离线),适合提示用户网络异常、离线缓存等场景:
xml
<template>
<div v-if="!isOnline" class="offline-tip">
❌ 网络已断开,请检查网络连接
</div>
</template>
<script setup lang="ts">
import { useNetwork } from '@vueuse/core'
const { isOnline, downlink } = useNetwork()
// isOnline:是否在线(布尔值)
// downlink:网络速度(Mbps)
</script>
3.2.3 useDark(深色模式切换)
快速实现深色/浅色模式切换,自动同步系统主题偏好,支持自定义主题类名:
xml
<template>
<div>
<h1>当前模式:{{ isDark ? '🌙 深色' : '☀️ 浅色' }}</h1>
<button @click="toggleDark()">切换主题</button>
</div>
</template>
<script setup lang="ts">
import { useDark, useToggle } from '@vueuse/core'
// 监听系统深色模式,同步到 html 标签的 class(默认添加 dark 类)
const isDark = useDark({
selector: 'html',
valueDark: 'dark',
valueLight: ''
})
// 结合 useToggle 实现切换
const toggleDark = useToggle(isDark)
</script>
<style>
html.dark {
background-color: #121212;
color: #fff;
}
</style>
3.2.4 useWindowSize(窗口尺寸监听)
实时获取窗口宽高,响应式更新,适合响应式布局、适配移动端/桌面端场景:
arduino
import { useWindowSize } from '@vueuse/core'
import { computed } from 'vue'
const { width, height } = useWindowSize()
// 判断是否为移动端(屏幕宽度 < 768px)
const isMobile = computed(() => width.value < 768)
3.3 表单与输入控制(优化交互体验)
封装防抖、节流、剪贴板等常用表单交互逻辑,简化输入框搜索、复制粘贴等功能开发。
3.3.1 useDebounce(防抖输入)
对输入值进行防抖处理,延迟执行逻辑,适合搜索框、输入验证等场景,避免频繁触发请求:
xml
<template>
<input
v-model="searchInput"
placeholder="请输入搜索关键词"
style="width: 300px; padding: 8px;"
/>
</template>
<script setup lang="ts">
import { ref, watch } from 'vue'
import { useDebounce } from '@vueuse/core'
const searchInput = ref('')
// 防抖处理:延迟500ms,返回防抖后的响应式值
const debouncedInput = useDebounce(searchInput, 500)
// 监听防抖后的值,触发搜索逻辑
watch(debouncedInput, (val) => {
if (val) {
console.log('搜索关键词:', val)
// 调用搜索接口...
}
})
</script>
3.3.2 useThrottle(节流控制)
限制函数执行频率,适合滚动事件、resize 事件等频繁触发的场景,优化性能:
javascript
import { useThrottle } from '@vueuse/core'
// 对窗口滚动事件进行节流,200ms内仅执行一次
const scrollY = useThrottle(window.scrollY, 200)
3.3.3 useCopyToClipboard(剪贴板操作)
简化复制文本到剪贴板的逻辑,自带复制状态反馈,无需编写原生 API 代码:
xml
<template>
<div>
<input v-model="copyText" placeholder="请输入要复制的内容" />
<button @click="copy()">{{ copied ? '已复制✅' : '点击复制' }}</button>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { useCopyToClipboard } from '@vueuse/core'
const copyText = ref('https://vueuse.org')
// 接收复制源,返回 [复制函数, 复制状态]
const { copy, copied } = useCopyToClipboard({ source: copyText })
</script>
3.4 DOM 操作与交互(简化 DOM 操作)
封装常用 DOM 操作逻辑,自动处理元素监听、尺寸获取、拖拽等功能,避免手动操作 DOM 带来的冗余代码。
3.4.1 useScroll(滚动位置监听)
监听元素或窗口的滚动位置,适合滚动加载、回到顶部、滚动导航等场景:
xml
<template>
<div ref="container" class="scroll-container">
<!-- 滚动内容 -->
</div>
<button @click="scrollToTop()" v-if="y > 100">回到顶部</button>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { useScroll } from '@vueuse/core'
const container = ref(null)
// 监听指定元素的滚动位置(默认监听窗口)
const { y, scrollTo } = useScroll(container)
// 回到顶部
const scrollToTop = () => {
scrollTo({ top: 0, behavior: 'smooth' })
}
</script>
3.4.2 useElementSize(元素尺寸监听)
实时获取元素的宽高,响应式更新,适合自适应布局、元素尺寸变化监听等场景:
xml
<template>
<div ref="box" class="box">自适应盒子</div>
<p>盒子尺寸:{{ width }}px × {{ height }}px</p>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { useElementSize } from '@vueuse/core'
const box = ref(null)
// 获取元素宽高(响应式)
const { width, height } = useElementSize(box)
</script>
3.4.3 onClickOutside(点击外部关闭)
监听元素外部的点击事件,适合弹窗、下拉菜单等场景,点击外部自动关闭:
xml
<template>
<button @click="isOpen = true">打开下拉菜单</button>
<div ref="menu" v-if="isOpen" class="menu">
下拉菜单内容
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { onClickOutside } from '@vueuse/core'
const isOpen = ref(false)
const menu = ref(null)
// 点击 menu 外部,关闭下拉菜单
onClickOutside(menu, () => {
isOpen.value = false
})
</script>
3.5 网络请求(简化请求逻辑)
封装 fetch API,自带加载状态、错误处理,返回响应式数据,适合简单网络请求场景,可替代 axios 基础用法。
3.5.1 useFetch(通用网络请求)
xml
<template>
<div>
<div v-if="isLoading">加载中...</div>
<div v-if="error" class="error">请求失败:{{ error.message }}</div>
<div v-if="data">{{ data.content }}</div>
</div>
</template>
<script setup lang="ts">
import { useFetch } from '@vueuse/core'
// 发起 GET 请求,返回响应式数据、加载状态、错误信息
const { data, isLoading, error, execute } = useFetch('https://api.example.com/data', {
method: 'GET',
// 可选配置:请求头、参数等
headers: { 'Content-Type': 'application/json' }
})
// 手动触发请求(如点击按钮发起请求)
// const handleFetch = () => execute()
</script>
四、VueUse 进阶技巧(实战提升)
4.1 函数组合使用
VueUse 的函数可自由组合,实现复杂功能,例如结合 useDark、useLocalStorage、useToggle 实现主题切换并持久化:
ini
import { useDark, useToggle, useLocalStorage } from '@vueuse/core'
// 结合本地存储,持久化主题状态
const theme = useLocalStorage('app_theme', 'light')
const isDark = useDark({ valueDark: 'dark', valueLight: 'light' })
// 同步主题状态与本地存储
theme.value = isDark.value ? 'dark' : 'light'
// 切换主题时同步更新本地存储
const toggleTheme = useToggle(isDark, [false, true])
toggleTheme(() => {
theme.value = isDark.value ? 'dark' : 'light'
})
4.2 自定义配置参数
大多数函数支持自定义配置,例如限制计数器范围、自定义本地存储键名、指定监听目标等,灵活适配业务需求:
php
// 1. 限制计数器范围(0-100)
const { count, inc } = useCounter(0, { min: 0, max: 100 })
// 2. 自定义本地存储键名和存储方式
const user = useLocalStorage('user_info', {}, {
storage: sessionStorage, // 改用 sessionStorage 存储
mergeDefaults: true // 合并默认值和存储值
})
// 3. 指定鼠标监听目标(仅在指定元素内监听)
const { x, y } = useMouse({ target: document.getElementById('container') })
4.3 避免常见误区
- 不要全局引入所有函数:VueUse 支持摇树优化,按需引入即可,全局引入(如
import * as VueUse from '@vueuse/core')会导致打包体积膨胀。 - 注意浏览器兼容性:部分函数(如 useBattery、useGeolocation)依赖浏览器原生 API,需做降级处理,避免在低版本浏览器中报错。
- Vue2 适配:VueUse v12.0 及以上版本不再支持 Vue2,若使用 Vue2 项目,需安装 v11.x 版本:
npm install @vueuse/core@11 -S。
五、常用函数速查表(快速查询)
| 函数分类 | 常用函数 | 核心功能 |
|---|---|---|
| 响应式状态 | useToggle、useCounter、useStorage | 布尔值切换、计数器、响应式存储 |
| 浏览器能力 | useMouse、useNetwork、useDark、useWindowSize | 鼠标监听、网络状态、深色模式、窗口尺寸 |
| 表单控制 | useDebounce、useThrottle、useCopyToClipboard | 防抖、节流、剪贴板操作 |
| DOM 操作 | useScroll、useElementSize、onClickOutside | 滚动监听、元素尺寸、点击外部关闭 |
| 网络请求 | useFetch、useWebSocket | 通用请求、WebSocket 连接 |
六、官方资源与学习渠道
- 官方中文文档:vueuse.nodejs.cn/(最权威,含交互式演示)
- GitHub 仓库:github.com/vueuse/vueu...(查看源码、提交 issues)
- 官方英文文档:vueuse.org/(最新更新、完整函数列表)
总结:VueUse 是 Vue3 开发的"效率神器",通过封装常用逻辑,大幅减少冗余代码,提升开发效率和代码可维护性。新手可从本文讲解的高频函数入手,结合官方文档,快速上手并应用到实际项目中,逐步掌握所有核心用法。