Vue3 组合式函数
什么是组合式函数
组合式函数(Composables)是利用 Vue 组合式 API 来封装和复用有状态逻辑的函数。
基本示例
useMouse
// composables/useMouse.js
import { ref, onMounted, onUnmounted } from 'vue'
export function useMouse() {
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))
return { x, y }
}
<script setup>
import { useMouse } from './composables/useMouse'
const { x, y } = useMouse()
</script>
<template>
<div>Mouse position: {{ x }}, {{ y }}</div>
</template>
useFetch
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()
} catch (err) {
error.value = err
} finally {
loading.value = false
}
}
fetchData()
return { data, error, loading }
}
useCounter
import { ref, computed } from 'vue'
export function useCounter(initialValue = 0) {
const count = ref(initialValue)
const increment = () => count.value++
const decrement = () => count.value--
const reset = () => count.value = initialValue
const isEven = computed(() => count.value % 2 === 0)
return {
count,
increment,
decrement,
reset,
isEven
}
}
实用组合式函数
useLocalStorage
import { ref, watch } from 'vue'
export function useLocalStorage(key, defaultValue) {
const storedValue = localStorage.getItem(key)
const value = ref(storedValue ? JSON.parse(storedValue) : defaultValue)
watch(value, (newValue) => {
localStorage.setItem(key, JSON.stringify(newValue))
}, { deep: true })
return value
}
useDebounce
import { ref, watch } from 'vue'
export function useDebounce(value, delay = 300) {
const debouncedValue = ref(value.value)
let timeout
watch(value, (newValue) => {
clearTimeout(timeout)
timeout = setTimeout(() => {
debouncedValue.value = newValue
}, delay)
})
return debouncedValue
}
useEventListener
import { onMounted, onUnmounted } from 'vue'
export function useEventListener(target, event, callback) {
onMounted(() => target.addEventListener(event, callback))
onUnmounted(() => target.removeEventListener(event, callback))
}
<script setup>
import { useEventListener } from './composables/useEventListener'
useEventListener(window, 'resize', () => {
console.log('Window resized')
})
</script>
useToggle
import { ref } from 'vue'
export function useToggle(initialValue = false) {
const state = ref(initialValue)
const toggle = () => {
state.value = !state.value
}
const setTrue = () => {
state.value = true
}
const setFalse = () => {
state.value = false
}
return {
state,
toggle,
setTrue,
setFalse
}
}
useAsync
import { ref } from 'vue'
export function useAsync(asyncFunction) {
const data = ref(null)
const error = ref(null)
const loading = ref(false)
async function execute(...args) {
loading.value = true
error.value = null
try {
data.value = await asyncFunction(...args)
} catch (err) {
error.value = err
} finally {
loading.value = false
}
}
return {
data,
error,
loading,
execute
}
}
VueUse 库
VueUse 是一个基于 Composition API 的实用函数集合。
yarn add @vueuse/core
<script setup>
import { useMouse, useLocalStorage, useToggle } from '@vueuse/core'
const { x, y } = useMouse()
const counter = useLocalStorage('counter', 0)
const [isOpen, toggle] = useToggle()
</script>