Files
blog-press/docs/Web/Vue/VueUse.md

3.2 KiB
Raw Blame History

title, date
title date
VueUse简介和使用 2026-06-05

一、安装

npm install @vueuse/core

二、使用

2.1 实时获取当前时间

<template>
  <div class="card">
    <p>当前时间: {{ formattedTime }}</p>
  </div>
</template>

<script setup>
import { useNow, useDateFormat } from '@vueuse/core'

// 获取当前时间响应式对象
const now = useNow()

// 格式化时间
const formattedTime = useDateFormat(now, 'YYYY-MM-DD HH:mm:ss')
</script>

2.2 useWebSocket

<script setup lang="ts">
iconst { status, send } = useWebSocket('wss://example.com/ws', {
  // 连接成功
  onConnected(ws) {
    console.log('WS connected')
  },
  // 收到消息
  onMessage(ws, event) {
    const msg = JSON.parse(event.data)
    console.log('receive:', msg)
  },
  // 断开
  onDisconnected(ws, event) {
    console.log('WS disconnected, code:', event.code)
  },
  onError(ws, event) {
    console.error('WS error', event)
  },
  autoReconnect: {
    retries: 3,
    delay: 1000
  }
})
</script>

2.3 防抖和节流

防抖 Debounce 节流 Throttle
执行时机 连续触发 停下后 每隔一段时间
执行次数 通常 1 次(最后) 多次,但受限制
典型场景 搜索联想、校验 滚动、拖拽

  防抖:

<template>
  <input @input="handleInput" placeholder="输入搜索关键字" />
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { useDebounceFn } from '@vueuse/core'

const keyword = ref('')

// 输入停止 500ms 后执行搜索
const debouncedSearch = useDebounceFn((val) => {
  console.log('发起搜索请求:', val)
  // api.search(val)
}, 500)

const handleInput = (e) => {
  keyword.value = e.target.value
  debouncedSearch(keyword.value)
}
</script>

  节流:

<template>
  <div style="padding: 20px">
    <p>点击次数被节流{{ count }}</p>
    <button @click="throttledClick">
      狂点我节流 500ms
    </button>
    <p style="color:#999;font-size:12px">
      快速连点也不会一直 +1 500ms 最多加一次
    </p>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import { useThrottleFn } from '@vueuse/core'

const count = ref(0)

// 节流函数500ms 内最多执行一次
const throttledClick = useThrottleFn(() => {
  count.value++
  console.log('真正执行 +1')
}, 500)
</script>

::: warning 如果是表单提交应该使用状态锁来限制即当提交后将按钮置为loading状态提交成功后再重置。

<template>
  <el-button
    type="primary"
    :loading="loading"
    @click="handleSubmit"
  >
    {{ loading ? '提交中...' : '提交' }}
  </el-button>
</template>

<script setup>
import { ref } from 'vue'
import { ElMessage } from 'element-plus'

const loading = ref(false)

const handleSubmit = async () => {
  if (loading.value) return
  loading.value = true

  try {
    // 模拟接口请求
    await submitForm()
    ElMessage.success('提交成功')
  } catch (err) {
    ElMessage.error('提交失败')
  } finally {
    loading.value = false
  }
}

const submitForm = () => {
  return new Promise(resolve => setTimeout(resolve, 1500))
}
</script>

:::