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

158 lines
3.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: VueUse简介和使用
date: 2026-06-05
---
# 一、安装
```bash
npm install @vueuse/core
```
# 二、使用
## 2.1 实时获取当前时间
```ts
<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
```ts
<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 次(最后) | 多次,但受限制 |
| **典型场景** | 搜索联想、校验 | 滚动、拖拽 |
&emsp;&emsp;防抖:
```vue
<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>
```
&emsp;&emsp;节流:
```vue
<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状态提交成功后再重置。
```vue
<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>
```
:::