20 个“拿来即用”的响应式组合式函数,让你少写 80% 代码!

94 阅读3分钟

🧰 20 个常用 VueUse 函数

下面是 20 个常用的 VueUse 函数,每个函数都包含作用、使用场景和示例代码。


1. useLocalStorage

✅ 作用

将数据双向绑定到 localStorage,刷新后自动恢复。

🧩 场景

主题色、侧边栏状态、购物车数量等“持久化”轻量数据。

💡 示例

<script setup>
import { useLocalStorage } from '@vueuse/core'

const ui = useLocalStorage('ui', { theme: 'light', sidebar: true })

function toggleSidebar() {
  ui.value.sidebar = !ui.value.sidebar
}
</script>

<template>
  <aside v-if="ui.sidebar">左侧菜单</aside>
  <button @click="toggleSidebar">展开/收起</button>
</template>

🧠 小结

一行代码完成“响应式 + 持久化”,不用手动 JSON.parse/stringify


2. useSessionStorage

✅ 作用

useLocalStorage 类似,但关闭标签页后失效。

🧩 场景

多步骤表单、页面搜索关键词、一次性引导。

💡 示例

<script setup>
import { useSessionStorage } from '@vueuse/core'

const step = useSessionStorage('reg-step', 1)
function next() {
  step.value++
}
</script>

<template>
  <h3>第 {{ step }} 步</h3>
  <button @click="next">下一步</button>
</template>

🧠 小结

适用于“本次访问”内的临时数据。


3. useDark

✅ 作用

一键检测并切换深色模式,自动写入 <html class="dark">

🧩 场景

夜间模式切换按钮。

💡 示例

<script setup>
import { useDark, useToggle } from '@vueuse/core'

const isDark = useDark()
const toggleDark = useToggle(isDark)
</script>

<template>
  <button @click="toggleDark()">
    {{ isDark ? '🌞' : '🌙' }}
  </button>
</template>

<style>
.dark {
  background: #111;
  color: #fff;
}
</style>

🧠 小结

无需手动监听 prefers-color-scheme,封装好所有逻辑。


4. useToggle

✅ 作用

将布尔值包装成“切换”函数。

🧩 场景

弹窗、展开/收起等“开/关”状态。

💡 示例

<script setup>
import { useToggle } from '@vueuse/core'

const [show, toggle] = useToggle(false)
</script>

<template>
  <button @click="toggle">打开弹窗</button>
  <div v-if="show" class="modal">
    内容
    <button @click="toggle">关闭</button>
  </div>
</template>

<style>
.modal {
  position: fixed;
  inset: 0;
  background: #0003;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #fff;
  width: 200px;
  height: 100px;
  margin: auto;
}
</style>

🧠 小结

语义清晰,省掉手动 ! 操作。


5. useClipboard

✅ 作用

读写系统剪贴板,支持权限提示和反馈。

🧩 场景

点击复制链接、验证码、代码片段等。

💡 示例

<script setup>
import { useClipboard } from '@vueuse/core'

const source = ref('https://vueuse.org')
const { copy, copied, isSupported } = useClipboard()
</script>

<template>
  <button v-if="isSupported" @click="copy(source)">
    {{ copied ? '✅ 已复制' : '复制链接' }}
  </button>
  <span v-else>浏览器不支持剪贴板</span>
</template>

🧠 小结

比手动写 navigator.clipboard.writeText 更优雅。


6. useFetch

✅ 作用

响应式 fetch,自动处理 loadingerrordata

🧩 场景

获取文章、用户信息、提交表单等。

💡 示例

<script setup>
import { useFetch } from '@vueuse/core'

const id = ref(1)
const { data, error, loading } = useFetch(
  () => `https://jsonplaceholder.typicode.com/posts/${id.value}`,
  { refetch: true }
)
</script>

<template>
  <button @click="id++">看下一篇文章</button>
  <div v-if="loading">加载中…</div>
  <div v-else-if="error">出错了:{{ error }}</div>
  <article v-else-if="data">
    <h3>{{ data.title }}</h3>
    <p>{{ data.body }}</p>
  </article>
</template>

🧠 小结

比原生 fetch 省 80% 样板代码。


7. useCounter

✅ 作用

自增、自减、范围限制。

🧩 场景

商品数量选择器、步进器。

💡 示例

<script setup>
import { useCounter } from '@vueuse/core'

const { count, inc, dec, set } = useCounter(1, { min: 1, max: 10 })
</script>

<template>
  <button @click="dec">-</button>
  <span>{{ count }}</span>
  <button @click="inc">+</button>
</template>

🧠 小结

边界处理封装好,逻辑清晰。


8. useInterval

✅ 作用

响应式定时器,自动暂停/恢复。

🧩 场景

倒计时、轮询订单状态、秒杀倒计时。

💡 示例

<script setup>
import { useInterval } from '@vueuse/core'

const { counter, pause, resume } = useInterval(1000, { controls: true })
</script>

<template>
  <p>已过去 {{ counter }} 秒</p>
  <button @click="pause">暂停</button>
  <button @click="resume">继续</button>
</template>

🧠 小结

比原生 setInterval 更智能。


9. usePreferredDark

✅ 作用

监听系统深色模式偏好。

🧩 场景

根据系统主题自动切换皮肤。

💡 示例

<script setup>
import { usePreferredDark } from '@vueuse/core'

const isPreferredDark = usePreferredDark()
</script>

<template>
  <div :class="{ dark: isPreferredDark }">
    系统当前喜欢 {{ isPreferredDark ? '黑夜' : '白天' }}
  </div>
</template>

<style>
.dark {
  background: #111;
  color: #fff;
}
</style>

🧠 小结

适合做默认主题判断。


10. useMediaQuery

✅ 作用

将媒体查询转为响应式布尔值。

🧩 场景

判断设备类型、控制业务逻辑。

💡 示例

<script setup>
import { useMediaQuery } from '@vueuse/core'

const isMobile = useMediaQuery('(max-width: 768px)')
</script>

<template>
  <component :is="isMobile ? 'MobileNav' : 'DesktopNav'" />
</template>

🧠 小结

不用手动监听 matchMedia


11. useMouse

✅ 作用

实时获取鼠标坐标。

🧩 场景

自定义 Tooltip、鼠标跟随特效。

💡 示例

<script setup>
import { useMouse } from '@vueuse/core'

const { x, y } = useMouse()
</script>

<template>
  <div class="ball" :style="{ left: x + 'px', top: y + 'px' }" />
</template>

<style>
.ball {
  position: fixed;
  width: 20px;
  height: 20px;
  background: red;
  border-radius: 50%;
  pointer-events: none;
  transform: translate(-50%, -50%);
}
</style>

🧠 小结

响应式坐标,直接用于模板。


12. useOnline

✅ 作用

监听网络在线/离线状态。

🧩 场景

断网提示、离线模式。

💡 示例

<script setup>
import { useOnline } from '@vueuse/core'

const online = useOnline()
</script>

<template>
  <div v-if="!online" class="tip">网络已断开,请检查连接</div>
</template>

<style>
.tip {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background: #ffeb3b;
  text-align: center;
  padding: 6px;
}
</style>

🧠 小结

跨浏览器兼容。


13. usePageLeave

✅ 作用

检测鼠标是否离开页面可视区域。

🧩 场景

挽留弹窗、优惠券提醒。

💡 示例

<script setup>
import { usePageLeave } from '@vueuse/core'

const isLeave = usePageLeave()
</script>

<template>
  <div v-if="isLeave" class="mask">
    <div class="dialog">
      别走!送你 10 元券~
      <button @click="isLeave = false">关闭</button>
    </div>
  </div>
</template>

<style>
.mask {
  position: fixed;
  inset: 0;
  background: #0006;
  display: flex;
  align-items: center;
  justify-content: center;
}

.dialog {
  background: #fff;
  padding: 20px;
  border-radius: 8px;
}
</style>

🧠 小结

一行搞定“鼠标离开”监听。


14. useStorageAsync

✅ 作用

异步序列化存储(如压缩、加密)。

🧩 场景

大数据量压缩、加密存储。

💡 示例

<script setup>
import { useStorageAsync } from '@vueuse/core'
import { compress, decompress } from 'lz-string'

const state = useStorageAsync(
  'conf',
  { bigList: [] },
  localStorage,
  {
    mergeDefaults: true,
    serializer: {
      read: (v) => (v ? JSON.parse(decompress(v)) : null),
      write: (v) => compress(JSON.stringify(v)),
    },
  }
)
</script>

🧠 小结

减少存储体积,提升性能。


15. useTitle

✅ 作用

响应式修改网页标题。

🧩 场景

路由切换、未读消息提示。

💡 示例

<script setup>
import { useTitle } from '@vueuse/core'
import { ref } from 'vue'

const msgCount = ref(3)
useTitle(() =>
  msgCount.value ? `(${msgCount.value}) 条新消息 - 我的站点` : '我的站点'
)
</script>

<template>
  <button @click="msgCount--">已读一条</button>
</template>

🧠 小结

标题自动响应状态变化。


16. useDebounce

✅ 作用

防抖输入,延迟执行。

🧩 场景

输入框实时搜索。

💡 示例

<script setup>
import { ref, watch } from 'vue'
import { useDebounce } from '@vueuse/core'

const keyword = ref('')
const debounced = useDebounce(keyword, 500)

watch(debounced, () => {
  console.log('真正去搜索:', debounced.value)
})
</script>

<template>
  <input v-model="keyword" placeholder="输入关键词" />
</template>

🧠 小结

省去手动防抖逻辑。


17. useThrottle

✅ 作用

节流,按固定时间间隔执行。

🧩 场景

滚动加载、坐标上报。

💡 示例

<script setup>
import { useThrottle, useMouse } from '@vueuse/core'

const { x } = useMouse()
const throttledX = useThrottle(x, 1000)
</script>

<template>
  <p>鼠标 X 每 1 秒更新一次:{{ throttledX }}</p>
</template>

🧠 小结

响应式节流,无需手动 setTimeout


18. usePreferredLanguages

✅ 作用

读取浏览器语言偏好列表。

🧩 场景

自动切换站点语言。

💡 示例

<script setup>
import { usePreferredLanguages } from '@vueuse/core'

const langs = usePreferredLanguages()
const best = langs.value[0] || 'en'
</script>

<template>
  <div>检测到您首选语言:{{ best }}</div>
</template>

🧠 小结

响应式监听语言变更。


19. useFavicon

✅ 作用

动态修改页面图标。

🧩 场景

未读红点、夜间模式图标切换。

💡 示例

<script setup>
import { useFavicon } from '@vueuse/core'
import { ref } from 'vue'

const dot = ref(false)
useFavicon(dot ? '/favicon-dot.ico' : '/favicon.ico')
</script>

<template>
  <button @click="dot = !dot">切换红点图标</button>
</template>

🧠 小结

自动管理 <link rel="icon">


20. useGeolocation

✅ 作用

获取用户地理位置。

🧩 场景

外卖、天气、打卡定位。

💡 示例

<script setup>
import { useGeolocation } from '@vueuse/core'

const { coords, located, error } = useGeolocation()

const lat = computed(() => coords.value?.latitude)
const lng = computed(() => coords.value?.longitude)
</script>

<template>
  <button v-if="!located" disabled>正在定位…</button>
  <div v-else-if="error">定位失败:{{ error.message }}</div>
  <div v-else>您当前位置:{{ lat.toFixed(6) }}, {{ lng.toFixed(6) }}</div>
</template>

🧠 小结

自动监听位置变化,响应式坐标。