VueUse:Composition API 时代的瑞士军刀
上周给新项目装依赖,npm i @vueuse/core 已经是肌肉记忆了。这个库现在 200+ 个组合式函数(composable),覆盖了浏览器 API、状态、传感器、动画等方方面面。
这篇不罗列 API(官方文档的搜索比我全),只讲我在生产项目里反复用到、且能明显少写代码的那些。
状态持久化:useLocalStorage
以前手写 localStorage 同步要处理序列化、读取兜底、跨标签页同步,现在一行:
import { useLocalStorage } from '@vueuse/core'
// 就是一个 ref,读写自动同步到 localStorage
const token = useLocalStorage('token', '')
const settings = useLocalStorage('settings', { theme: 'light', fontSize: 14 })
settings.value.theme = 'dark' // 自动序列化存进去
刷新页面数据还在,多个标签页之间还会自动同步(基于 storage 事件)。自己封装这一套至少要五十行。
网络请求:useFetch
不是简单包一层 fetch,而是把"加载态、错误态、响应解析"都做成响应式:
import { useFetch } from '@vueuse/core'
const { data, isFetching, error, execute } = useFetch('/api/users')
.get()
.json()
// data 是响应式的,模板里直接 {{ data.list }}
// 需要重新请求就调 execute()
url 也可以是响应式的——这是我认为最妙的设计:
const page = ref(1)
const url = computed(() => `/api/users?page=${page.value}`)
const { data } = useFetch(url).get().json()
page.value = 2 // url 变化自动触发重新请求,不用 watch
事件与交互:告别手动 addEventListener
import { useEventListener, useMouse, useWindowSize } from '@vueuse/core'
// 组件卸载自动移除监听,再也不怕忘
useEventListener(document, 'keydown', (e) => {
if (e.key === 'Escape') closeModal()
})
// 鼠标位置、窗口尺寸都是响应式的
const { x, y } = useMouse()
const { width, height } = useWindowSize()
自己写 onMounted 里 add、onUnmounted 里 remove,写十次总会漏一次。VueUse 把这些样板代码彻底消灭了。
工具型三剑客
防抖节流:
import { refDebounced, useThrottleFn } from '@vueuse/core'
const input = ref('')
const debounced = refDebounced(input, 300) // 300ms 后才同步的 ref
watch(debounced, (val) => search(val))
剪贴板:
import { useClipboard } from '@vueuse/core'
const { copy, copied, isSupported } = useClipboard()
// copied 复制成功后变 true,1.5 秒后自动恢复 false,直接拿来显示"已复制"提示
点击元素外部:
import { onClickOutside } from '@vueuse/core'
const dropdownRef = ref(null)
onClickOutside(dropdownRef, () => {
showDropdown.value = false
})
对比我上篇手写的 v-click-outside 指令,这个方案连指令都省了。
文档与标题:useTitle / useFavicon
import { useTitle } from '@vueuse/core'
const route = useRoute()
const title = computed(() => `${route.meta.title} - 我的站点`)
useTitle(title) // 路由变化,标题自动跟着变
SPA 改 document.title 的需求从此不用写 watch 了。
什么时候不该用 VueUse
用了一年多,也总结出边界:
- 强业务逻辑别塞进去:VueUse 管的是"通用能力",你的订单状态机、表单校验规则还是该自己写 composable
- 注意打包体积:虽然支持 tree-shaking,用几个进包几个,但
@vueuse/integrations里的集成(比如 qrcode、focus-trap)会带进对应第三方库,看清再装 - 团队规范先行:同一个功能有人用 VueUse 有人手写,还不如统一手写。引入前先和团队对齐
小结
- useLocalStorage、useFetch、useEventListener、refDebounced、onClickOutside 是我的五大金刚
- 响应式 URL 触发请求是 useFetch 最优雅的设计
- VueUse 的价值不止是少写代码,更是把"清理副作用"这类容易遗漏的细节给兜住了
- 通用能力交给它,业务逻辑还是自己的 composable
Composition API 最大的红利就是这类库的诞生——逻辑终于可以像积木一样自由组合了。还没上车的同学,从 useLocalStorage 开始试,十分钟就能感受到真香。
看到这里了?如果这篇文章帮到过你
请我喝瓶可乐就好 🥤

评论0 条
还没有评论,来抢沙发~