Appearance
注意
vueuse真的有好多超级好用的函数(设备位置和方向变化速度、捕获用户屏幕、窗口或浏览器标签页的内容等等等,超级超级多好用的函数),这里只记录的自己实际用过的
useRefHistory
跟踪响应式数据的更改(跟踪ref所做的每个更改存储到数组中,可以撤销和重做)
vue
<script setup>
import { ref } from 'vue'
import { useRefHistory } from '@vueuse/core'
const counter = ref(0)
const { history, undo, redo } = useRefHistory(counter)
</script>
<template>
<div class="flex items-center">
<el-button @click="counter++">+</el-button>
<h2 class="mx-4">{{ counter }}</h2>
<el-button @click="counter--">-</el-button>
<el-button @click="undo">撤销</el-button>
<el-button @click="redo">重做</el-button>
</div>
<div class="flex flex-col">
<div v-for="(item, index) in history" :key="index">
{{ item }}
</div>
</div>
</template>
onClickOutside
监听元素外部的点击
vue
<script setup>
import { ref, useTemplateRef } from 'vue'
import { onClickOutside } from '@vueuse/core'
import { vOnClickOutside } from '@vueuse/components'
const visible = ref(false)
const modalRef = useTemplateRef('modalRef')
onClickOutside(modalRef, (event) => {
console.log(event)
console.log('点击了dialog外层')
visible.value = false
})
function openDialog() {
visible.value = true
}
function closeDialog() {
console.log('指令形式')
visible.value = false
}
</script>
<template>
<el-button type="primary" @click="openDialog">open dialog</el-button>
<div class="w-100 h-40 bg-coolGray" v-if="visible" ref="modalRef" v-on-click-outside="closeDialog">我是dialog</div>
</template>
useBattery
获取和监控设备的电池状态
- charging: 是否正在充电
- chargingTime: 剩余的充电时间
- dischargingTime: 剩余的使用时间
- level: 电池电量百分比
useFps
监控和调整应用程序的帧率
vue
<script setup>
import { useFps } from '@vueuse/core'
const fps = useFps()
</script>
useGeolocation
获取用户的地理位置(需要授权)
vue
<script setup>
import { useGeolocation } from '@vueuse/core'
const { coords, locatedAt, error, resume, pause } = useGeolocation()
</script>
- coords: 当前位置信息(经纬度、海拔、精度、方向、速度)
- locatedAt最后一次定位时间
- error: 定位失败错误对象
- resume: 恢复定位
- pause: 暂停定位
useInfiniteScroll
监听元素是否滚动到底部(可监听任意元素)
vue
<script setup>
import { ref, useTemplateRef } from 'vue'
import { useInfiniteScroll } from '@vueuse/core'
const el = useTemplateRef('el')
const data = ref([])
const { reset } = useInfiniteScroll(
el,
() => {
const length = data.value.length + 1
data.value.push(...Array.from({ length: 5 }, (_, i) => length + i))
},
{ distance: 10 }
)
function resetList() {
data.value = []
reset()
}
</script>
<template>
<div ref="el" class="flex flex-col gap-2 p-4 w-300px h-300px m-auto overflow-y-scroll bg-gray-500/5 rounded">
<div v-for="item in data" :key="item" class="h-15 bg-gray-500/5 rounded p-3">
{{ item }}
</div>
</div>
<button @click="resetList()">Reset</button>
</template>
useMouse
获取鼠标位置
ts
import { useMouse } from '@vueuse/core'
const { x, y, sourceType } = useMouse()
useDraggable
拖动元素
vue
<script setup>
import { useTemplateRef } from 'vue'
import { useDraggable } from '@vueuse/core'
const el = useTemplateRef('el')
const { x, y, style } = useDraggable(el, {
initialValue: { x: 80, y: 80 },
preventDefault: true
})
</script>
<template>
<div
ref="el"
p="x-4 y-2"
border="~ gray-800/30 rounded"
shadow="~ hover:lg"
class="fixed bg-blueGray cursor-move"
style="touch-action: none"
:style="style"
>
拖拽
<div class="text-sm opacity-50">I am at {{ Math.round(x) }}, {{ Math.round(y) }}</div>
</div>
</template>
useInterval
创建一个定时器,在指定的时间间隔内重复执行一个函数
vue
<script setup>
import { useInterval } from '@vueuse/core'
const counter = useInterval(200)
</script>
<template>
<div>
<p>{{ counter }}</p>
</div>
</template>
useBase64
将文本、缓冲区、文件、画布、对象、映射、集和、图片转base64
ts
import { useBase64 } from '@vueuse/core'
import { Ref, ref } from 'vue'
const text = ref('')
const { base64 } = useBase64(text)
useDebounceFn
防抖
js
<script setup>
import { ref } from "vue";
import { useDebounceFn } from "@vueuse/core";
const query = ref("");
const result = ref("");
const search = (query) => {
// 模拟搜索操作
result.value = `搜索结果为: ${query}`;
};
// 使用 useDebounceFn 创建防抖函数
const onInput = useDebounceFn((event) => {
search(event.target.value);
}, 500); // 500 毫秒的防抖时间
</script>
<template>
<div>
<input v-model="query" @input="onInput" placeholder="输入搜索内容..." />
<p>搜索结果: {{ result }}</p>
</div>
</template>
useThrottleFn
节流
vue
<script setup lang="ts">
import { useThrottleFn } from '@vueuse/core'
import { ref } from 'vue'
const updated = ref(0)
const clicked = ref(0)
const throttledFn = useThrottleFn(() => {
updated.value += 1
}, 1000)
function clickedFn() {
clicked.value += 1
throttledFn()
}
</script>
<template>
<div>
<button @click="clickedFn">click</button>
<p>{{ clicked }}</p>
<p>{{ updated }}</p>
</div>
</template>
useClipboard
复制文本到剪贴板
vue
<script setup>
import { useClipboard } from '@vueuse/core'
import { ref } from 'vue'
const input = ref('')
const { text, isSupported, copy } = useClipboard()
</script>
<template>
<div v-if="isSupported">
<p>
剪切板: <code>{{ text }}</code>
</p>
<input v-model="input" type="text" />
<button @click="copy(input)">复制</button>
</div>
</template>
useFileDialog
选择文件
vue
<script setup>
import { useFileDialog } from '@vueuse/core'
const { files, open, reset, onCancel, onChange } = useFileDialog()
onChange((files) => {
console.log('🚀 ~ onChange ~ files:', files)
})
onCancel(() => {})
</script>
<template>
<button type="button" @click="open">选择文件</button>
</template>
useFullscreen
全屏
vue
<script setup>
import { useFullscreen } from '@vueuse/core'
import { useTemplateRef } from 'vue'
const el = useTemplateRef('el')
const { toggle } = useFullscreen(el)
</script>
<template>
<div class="text-center">
<div class="size-100 bg-amber" ref="el"></div>
<button @click="toggle">全屏</button>
</div>
</template>