Appearance
VueUse Usage Style
Introduction
VueUse is a collection of useful composables for Vue.js. This guide explains how to use them correctly.
Installation and Setup
Installation
bash
npm install @vueuse/coreBasic Usage
javascript
import { useLocalStorage, useMouse } from '@vueuse/core'Commonly Used Composables
useLocalStorage
For storing data in localStorage:
javascript
import { useLocalStorage } from '@vueuse/core'
// Simple usage
const count = useLocalStorage('count', 0)
// With advanced settings
const user = useLocalStorage('user', null, {
serializer: {
read: (v) => JSON.parse(v),
write: (v) => JSON.stringify(v)
}
})useMouse
For tracking mouse position:
javascript
import { useMouse } from '@vueuse/core'
const { x, y } = useMouse()
// Usage in template
// <div>Mouse position: {{ x }}, {{ y }}</div>useWindowSize
For tracking window size:
javascript
import { useWindowSize } from '@vueuse/core'
const { width, height } = useWindowSize()
// responsive design
const isMobile = computed(() => width.value < 768)useFetch
For HTTP requests:
javascript
import { useFetch } from '@vueuse/core'
const { data, error, isLoading } = await useFetch('/api/users')
// With settings
const { data: posts } = await useFetch('/api/posts', {
headers: {
'Authorization': `Bearer ${token}`
}
})useDebounceFn
For debouncing functions:
javascript
import { useDebounceFn } from '@vueuse/core'
const debouncedSearch = useDebounceFn((query) => {
// search in API
searchAPI(query)
}, 300)
// Usage
const handleInput = (event) => {
debouncedSearch(event.target.value)
}useThrottleFn
For throttling functions:
javascript
import { useThrottleFn } from '@vueuse/core'
const throttledScroll = useThrottleFn(() => {
// handle scroll
console.log('scrolled')
}, 100)
// Usage in event listener
window.addEventListener('scroll', throttledScroll)Composables for Forms
useVModel
For two-way v-model:
javascript
import { useVModel } from '@vueuse/core'
// in child component
const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])
const value = useVModel(props, 'modelValue', emit)useForm
For form management:
javascript
import { useForm } from '@vueuse/core'
const { data, errors, validate, reset } = useForm({
username: '',
email: '',
password: ''
})
const handleSubmit = async () => {
const { valid } = await validate()
if (valid) {
// submit form
}
}Composables for Animation
useTransition
For smooth animations:
javascript
import { useTransition } from '@vueuse/core'
const source = ref(0)
const output = useTransition(source)
// gradual change
source.value = 100useSpring
For spring animations:
javascript
import { useSpring } from '@vueuse/core'
const target = ref(0)
const spring = useSpring(target, {
stiffness: 0.1,
damping: 0.8
})Best Practices
Performance
- Use
shallowReffor large data - Use
computedfor complex calculations - Use
watchEffectfor side effects
Error Handling
javascript
import { useFetch } from '@vueuse/core'
const { data, error, isLoading } = await useFetch('/api/data')
// Error handling
if (error.value) {
console.error('Error fetching data:', error.value)
}Cleanup
javascript
import { onUnmounted } from 'vue'
import { useEventListener } from '@vueuse/core'
const stop = useEventListener(window, 'resize', handleResize)
// cleanup on unmount
onUnmounted(() => {
stop()
})Practical Examples
Counter Component with localStorage
vue
<template>
<div>
<p>Count: {{ count }}</p>
<button @click="increment">Increment</button>
<button @click="reset">Reset</button>
</div>
</template>
<script setup>
import { useLocalStorage } from '@vueuse/core'
const count = useLocalStorage('counter', 0)
const increment = () => {
count.value++
}
const reset = () => {
count.value = 0
}
</script>Search Component with debounce
vue
<template>
<div>
<input
v-model="searchQuery"
placeholder="Search..."
@input="handleSearch"
/>
<div v-if="isLoading">Loading...</div>
<div v-else>
<div v-for="result in searchResults" :key="result.id">
{{ result.title }}
</div>
</div>
</div>
</template>
<script setup>
import { ref, computed } from 'vue'
import { useDebounceFn, useFetch } from '@vueuse/core'
const searchQuery = ref('')
const debouncedSearch = useDebounceFn(async (query) => {
if (query.trim()) {
const { data } = await useFetch(`/api/search?q=${query}`)
searchResults.value = data.value
}
}, 300)
const handleSearch = () => {
debouncedSearch(searchQuery.value)
}
</script>