来电秀秀免费版
83.28MB · 2025-11-04
在Vue 3的生态系统中,组合式API(Composition API)为我们带来了更灵活的代码组织方式。而VueUse作为Vue生态中最受欢迎的工具库之一,为开发者提供了200多个实用的组合式函数,极大地简化了日常开发工作。本期我们将深入探索VueUse这个强大的工具库。
VueUse是一个基于Vue组合式API的实用工具库,它将常见的开发需求封装成可复用的组合式函数。主要特点包括:
# 使用 pnpm(推荐)
pnpm add @vueuse/core
# 安装额外的集成包
pnpm add @vueuse/components @vueuse/integrations
<template>
  <div>
    <p>鼠标位置: {{ x }}, {{ y }}</p>
    <p>窗口大小: {{ width }} x {{ height }}</p>
    <button @click="toggle">
      {{ isOnline ? '在线' : '离线' }}
    </button>
  </div>
</template>
<script setup>
import { useMouse, useWindowSize, useOnline } from '@vueuse/core'
// 获取鼠标位置
const { x, y } = useMouse()
// 获取窗口大小
const { width, height } = useWindowSize()
// 检测网络状态
const { isOnline, toggle } = useOnline()
</script>
// 响应式的本地存储
const name = useLocalStorage('user-name', '默认值')
const settings = useSessionStorage('app-settings', { theme: 'light' })
// 布尔值切换
const [isVisible, toggle] = useToggle()
const [status, toggleStatus] = useToggle('active', 'inactive')
// 计数器管理
const { count, inc, dec, set, reset } = useCounter(0, { min: 0, max: 100 })
// 鼠标位置和状态
const { x, y } = useMouse()
const { pressed } = useMousePressed()
// 键盘事件
const { ctrl, shift, alt, meta } = useKeyModifier()
const keys = useKeyboard()
// 剪贴板操作
const { text, copy, copied, isSupported } = useClipboard()
// 全屏控制
const { isFullscreen, enter, exit, toggle } = useFullscreen()
// 设备方向
const { alpha, beta, gamma, absolute } = useDeviceOrientation()
// 地理位置
const { coords, locatedAt, error } = useGeolocation()
// 电池状态
const { charging, level, dischargingTime } = useBattery()
// HTTP请求
const { data, error, isFetching } = useFetch('/api/users')
// WebSocket连接
const { status, data, send, open, close } = useWebSocket('ws://localhost:8080')
// 数值过渡动画
const source = ref(0)
const output = useTransition(source, {
  duration: 1000,
  transition: TransitionPresets.easeInOutCubic
})
// 定时器管理
const { pause, resume, isActive } = useInterval(() => {
  console.log('每秒执行')
}, 1000)
// 元素尺寸监听
const el = ref()
const { width, height } = useElementSize(el)
// 元素可见性检测
const target = ref()
const { isIntersecting } = useIntersectionObserver(target)
// 元素大小变化监听
const el = ref()
useResizeObserver(el, (entries) => {
  console.log('元素大小改变')
})
// 防抖和节流
const input = ref('')
const debouncedValue = useDebounce(input, 500)
const throttledValue = useThrottle(input, 1000)
// 异步状态管理
const { state, isReady, isLoading, error, execute } = useAsyncState(
  () => fetchUserData(),
  null
)
// 双向绑定辅助
const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])
const data = useVModel(props, 'modelValue', emit)
<template>
  <div class="responsive-layout">
    <aside v-if="!isMobile" class="sidebar">
      侧边栏内容
    </aside>
    <main :class="{ 'full-width': isMobile }">
      <header>
        <button @click="toggleTheme">
          {{ isDark ? '' : '️' }}
        </button>
      </header>
      <div class="content">
        主要内容区域
      </div>
    </main>
  </div>
</template>
<script setup>
import { useBreakpoints, useDark, useToggle } from '@vueuse/core'
// 响应式断点
const breakpoints = useBreakpoints({
  mobile: 768,
  tablet: 1024,
  desktop: 1280
})
const isMobile = breakpoints.smaller('tablet')
// 暗黑模式
const isDark = useDark()
const toggleTheme = useToggle(isDark)
</script>
<template>
  <div class="dashboard">
    <div class="status-bar">
      <span :class="{ online: isOnline, offline: !isOnline }">
        {{ isOnline ? '在线' : '离线' }}
      </span>
      <span>电池: {{ batteryLevel }}%</span>
      <span>{{ formattedTime }}</span>
    </div>
    
    <div class="charts">
      <canvas ref="chartCanvas"></canvas>
    </div>
    
    <div class="controls">
      <button @click="startMonitoring" :disabled="isMonitoring">
        开始监控
      </button>
      <button @click="stopMonitoring" :disabled="!isMonitoring">
        停止监控
      </button>
    </div>
  </div>
</template>
<script setup>
import { 
  useOnline, 
  useBattery, 
  useNow, 
  useInterval,
  useElementSize 
} from '@vueuse/core'
// 网络状态
const isOnline = useOnline()
// 电池状态
const { level: batteryLevel } = useBattery()
// 实时时间
const now = useNow()
const formattedTime = computed(() => 
  now.value.toLocaleTimeString()
)
// 图表容器
const chartCanvas = ref()
const { width, height } = useElementSize(chartCanvas)
// 监控控制
const isMonitoring = ref(false)
const { pause, resume } = useInterval(() => {
  // 更新图表数据
  updateChartData()
}, 1000, { immediate: false })
const startMonitoring = () => {
  isMonitoring.value = true
  resume()
}
const stopMonitoring = () => {
  isMonitoring.value = false
  pause()
}
</script>
<template>
  <form @submit.prevent="handleSubmit">
    <div class="form-group">
      <input 
        v-model="form.email" 
        type="email" 
        placeholder="邮箱"
        :class="{ error: emailError }"
      >
      <span v-if="emailError" class="error-text">
        {{ emailError }}
      </span>
    </div>
    
    <div class="form-group">
      <input 
        v-model="form.password" 
        type="password" 
        placeholder="密码"
      >
    </div>
    
    <button 
      type="submit" 
      :disabled="!isFormValid || isSubmitting"
    >
      {{ isSubmitting ? '提交中...' : '登录' }}
    </button>
    
    <div v-if="submitError" class="error">
      {{ submitError }}
    </div>
  </form>
</template>
<script setup>
import { 
  useVModel, 
  useAsyncValidator, 
  useAsyncState,
  useDebounce 
} from '@vueuse/core'
// 表单数据
const form = reactive({
  email: '',
  password: ''
})
// 邮箱验证(防抖)
const debouncedEmail = useDebounce(() => form.email, 500)
const { pass: isEmailValid, errorMessage: emailError } = useAsyncValidator(
  debouncedEmail,
  async (value) => {
    if (!value) return '邮箱不能为空'
    if (!/S+@S+.S+/.test(value)) return '邮箱格式不正确'
    
    // 异步验证邮箱是否已注册
    const exists = await checkEmailExists(value)
    if (!exists) return '邮箱未注册'
    
    return true
  }
)
// 表单验证
const isFormValid = computed(() => 
  isEmailValid.value && form.password.length >= 6
)
// 提交处理
const { 
  state: submitResult, 
  isLoading: isSubmitting, 
  error: submitError, 
  execute: submitForm 
} = useAsyncState(
  () => loginUser(form),
  null,
  { immediate: false }
)
const handleSubmit = () => {
  if (isFormValid.value) {
    submitForm()
  }
}
</script>
// 推荐:按需引入
import { useMouse, useLocalStorage } from '@vueuse/core'
// 避免:全量引入
import * as VueUse from '@vueuse/core'
// 合理利用响应式特性
const { x, y } = useMouse()
const position = computed(() => `${x.value}, ${y.value}`)
// 避免不必要的响应式转换
const staticConfig = { timeout: 5000 } // 静态配置无需响应式
const { data, error, isFinished } = useFetch('/api/data')
watchEffect(() => {
  if (error.value) {
    console.error('请求失败:', error.value)
    // 处理错误逻辑
  }
})
VueUse是Vue生态系统中不可或缺的工具库,它通过提供丰富的组合式函数,极大地提升了Vue开发的效率和体验。无论是处理浏览器API、状态管理,还是实现复杂的交互效果,VueUse都能提供优雅的解决方案。
推荐使用场景:
VueUse不仅是一个工具库,更是学习Vue组合式API最佳实践的优秀范例。通过研究其源码和使用方式,能够帮助开发者更好地理解和运用Vue 3的核心特性。