你是不是经常在Vue项目里写着写着就发现,相似的逻辑在不同的组件里复制粘贴?每次都要重新写一遍鼠标跟踪、本地存储这些功能,既浪费时间又容易出错?
别担心!今天我就带你玩转Vue 3的组合式函数(Composables),教你如何把常用逻辑封装成自己的"武器库"。看完本文,你会掌握组合式函数的精髓,还能直接拿走3个即插即用的实用函数!
什么是组合式函数?为啥要用它?
简单说,组合式函数就是Vue 3里让你把逻辑"打包带走"的利器。它让你能把组件里零散的逻辑代码抽出来,变成可以复用的函数,就像React里的hooks一样好用。
用组合式函数有三大好处:代码更整洁、逻辑更好复用、维护更轻松。比如说,你封装了一个useMouse
,以后在任何组件里想用鼠标位置,一行代码就搞定了!
手把手教你写3个实用组合函数
1. useMouse:实时追踪鼠标位置
先来看个最简单的------获取鼠标在页面中的实时位置。不用再在每个组件里写一堆事件监听了!
javascript
import { ref, onMounted, onUnmounted } from 'vue'
// 导出一个叫useMouse的函数
export function useMouse() {
// 用ref创建响应式的x和y坐标
const x = ref(0)
const y = ref(0)
// 处理鼠标移动的函数
function update(event) {
x.value = event.pageX
y.value = event.pageY
}
// 组件挂载时添加监听
onMounted(() => window.addEventListener('mousemove', update))
// 组件卸载时移除监听(重要!避免内存泄漏)
onUnmounted(() => window.removeEventListener('mousemove', update))
// 返回x和y,这样组件里就能用了
return { x, y }
}
在组件里用起来超级简单:
html
<template>
<div>鼠标位置:{{ x }}, {{ y }}</div>
</template>
<script setup>
import { useMouse } from './useMouse'
// 一行代码搞定鼠标追踪!
const { x, y } = useMouse()
</script>
2. useLocalStorage:自动同步本地存储
接下来这个更实用!让你像用ref一样用localStorage,数据自动持久化到浏览器。
javascript
import { ref, watch } from 'vue'
export function useLocalStorage(key, defaultValue) {
// 尝试从localStorage读取初始值
const data = ref(JSON.parse(localStorage.getItem(key)) || defaultValue)
// 监听数据变化,自动保存到localStorage
watch(data, (newValue) => {
localStorage.setItem(key, JSON.stringify(newValue))
}, { deep: true }) // deep: true确保对象内部变化也能监听到
return data
}
在组件中使用:
html
<template>
<div>
<input v-model="username" placeholder="输入用户名">
<div>保存的用户名:{{ username }}</div>
</div>
</template>
<script setup>
import { useLocalStorage } from './useLocalStorage'
// 像普通ref一样用,但数据会自动保存!
const username = useLocalStorage('username', '默认用户')
</script>
3. useFetch:优雅处理网络请求
最后一个来点高级的------封装网络请求,带加载状态和错误处理。
javascript
import { ref } from 'vue'
export function useFetch(url) {
const data = ref(null)
const error = ref(null)
const loading = ref(false)
async function fetchData() {
loading.value = true
try {
const response = await fetch(url)
data.value = await response.json()
error.value = null
} catch (err) {
error.value = err.message
data.value = null
} finally {
loading.value = false
}
}
// 立即执行一次请求
fetchData()
return { data, error, loading, fetchData }
}
在组件中使用:
html
<template>
<div v-if="loading">加载中...</div>
<div v-else-if="error">出错啦:{{ error }}</div>
<div v-else>{{ data }}</div>
<button @click="fetchData">重新加载</button>
</template>
<script setup>
import { useFetch } from './useFetch'
const { data, error, loading, fetchData } = useFetch('/api/user-info')
</script>
组合式函数的最佳实践
写了这么多函数,总结几个实用小技巧:
给函数名加上use
前缀,一看就知道是组合式函数。返回多个值的时候最好用对象而不是数组,这样在用的时候可以按需解构,不用管顺序。
记得处理副作用!在onUnmounted里清理事件监听、定时器这些资源,不然容易内存泄漏。
参数支持灵活一点,可以用ref也可以直接用值,这样用起来更方便:
javascript
export function useSomething(value) {
// 判断是不是ref,不是的话包裹一下
const valueRef = isRef(value) ? value : ref(value)
// ...其他逻辑
}
总结一下
好了,今天带你玩了3个超实用的Vue 3组合式函数。从鼠标跟踪到本地存储,再到网络请求,这些都是日常开发中最常用的功能。
组合式函数的魅力就在于,一次封装,到处使用。不仅能减少重复代码,还能让组件更专注于渲染逻辑,代码结构清晰多了。
你现在是不是已经跃跃欲试,想把自己的业务逻辑也封装起来了?其实组合式函数还能玩出更多花样,比如useTimer、useDrag、usePermission等等,只有想不到,没有封装不了!
你平时开发中还会封装哪些实用的组合函数?欢迎在评论区分享你的创意,或者说说你在使用组合式函数时遇到的问题,我们一起交流进步!