浏览器

使用屏幕断点

1import { useBreakpoints } from '@vueuse/core'
2/**
3 * 浏览器屏幕断点
4 */
5export function handleBreakpoints() {
6  const breakpoints = useBreakpoints({
7    xs: 0,
8    sm: 768,
9    md: 992,
10    lg: 1200,
11    xl: 1920,
12    xxl: 2560,
13  })
14  const xs = breakpoints.between('xs', 'sm')
15  const sm = breakpoints.between('sm', 'md')
16  const md = breakpoints.between('md', 'lg')
17  const lg = breakpoints.between('lg', 'xl')
18  const xl = breakpoints.between('xl', 'xxl')
19
20  return { xs, sm, md, lg, xl }
21}

复制文字

1import { useClipboard } from '@vueuse/core';
2/**
3 * 复制文字
4 * @param text 要复制的内容
5 */
6export const handleClipboard = (text: string) => useClipboard().copy(text);

事件监听

1import { useEventListener } from '@vueuse/core'
2
3const el = ref < HTMLElement | null > (null) // dom 元素
4useEventListener(el, 'click', () => {}) // 会在 dom 存在时自动注册事件,dom 被删除时会自动取消监听

取色器

1import { useEyeDropper } from '@vueuse/core'
2const {
3  isSupported, // 是否支持
4  open, // 打开取色
5  sRGBHex, // 16 进制色值
6} = useEyeDropper()

网站图标

1import { useFavicon } from '@vueuse/core'
2const icon = useFavicon()
3icon.value = 'dark.png' // 修改当前网站的图标

全屏元素

1import { useFullscreen } from '@vueuse/core'
2const el = ref < HTMLElement | null > (null)
3const {
4  isFullscreen, // 是否全屏
5  enter, // 进入全屏
6  exit, // 退出全屏
7  toggle, // 切换
8} = useFullscreen(el) // 传如 dom 元素

异步加载图片

1<script setup>
2  import { useImage } from '@vueuse/core';
3
4  const avatarUrl = 'https://place.dog/300/200';
5  const { isLoading } = useImage({ src: avatarUrl });
6</script>
7
8<template>
9  <span v-if="isLoading">Loading</span>
10  <img v-else :src="avatarUrl" />
11</template>

加载 script 标签

1import { useScriptTag } from '@vueuse/core';
2useScriptTag('https://player.twitch.tv/js/embed/v1.js', (el: HTMLScriptElement) => {});
3
4// 或手动控制加载
5const { scriptTag, load, unload } = useScriptTag('https://player.twitch.tv/js/embed/v1.js', () => {}, { manual: true });
6
7await load();
8await unload();

加载 css 字符串

  • 输入
1import { useStyleTag } from '@vueuse/core'
2
3const { id, css, load, unload, isLoaded } = useStyleTag('.home { margin-top: 32px; }')
4
5css.value = '.home { margin-top: 64px; }'
  • 输出
1<style type="text/css" id="vueuse_styletag_1">
2  .foo {
3    margin-top: 64px;
4  }
5</style>

网站标题

1import { useTitle } from '@vueuse/core'
2
3const title = useTitle('初始标题') // 可传入 computed 属性
4// const title = useTitle('新标题', { titleTemplate: '%s | 默认值' }) // 新标题将会替换 %s
5console.log(title.value) // 输出当前标题
6title.value = 'Hello' // 修改标题

url 查询参数

  • history
1// 当前 url:localhost/?foo=fao
2const params = useUrlSearchParams('history')
3console.log(params.foo) // fao
4params.foo = 'bar'
5params.vueuse = 'some'
6// 当前 url:localhost/?foo=bar&vueuse=awesome
  • hash
1const params = useUrlSearchParams('hash')
2params.foo = 'bar'
3params.vueuse = 'some'
4// 当前 url:localhost/#/?foo=bar&vueuse=some

系统通知

1import { useWebNotification } from '@vueuse/core'
2const {
3  isSupported, // 是否支持
4  notification, // 原数据
5  show,
6  close,
7  onClick,
8  onShow,
9  onError,
10  onClose,
11} = useWebNotification({
12  title: '标题',
13  body: '正文',
14  dir: 'rtl', // 文本方向 "auto" | "ltr" | "rtl"
15  lang: 'en', // 通知语言
16  tag: 'test', // 通知 id
17  icon: '', // 通知图标
18  renotify: true, // 是否在新的通知替换旧的通知
19  requireInteraction: false, // 是否保持活跃,直到用户点击关闭才消失
20  silent: false, // 是否静音,关闭震动
21  vibrate: [], // 指定具有震动的硬件发出震动
22})
23
24isSupported && show()
25
26onClick.on(() => {
27  console.log('click')
28})

传感器

键盘事件

1import { onKeyStroke } from '@vueuse/core'
2
3onKeyStroke('ArrowDown', (e) => {
4  console.log('按了↓')
5})
6
7// 监听多个键
8onKeyStroke(['s', 'S', 'ArrowDown'], (e) => {
9  console.log(`按了${e.key}`)
10})
11
12// 指定目标元素
13onKeyStroke(
14  'A',
15  (e) => {
16    console.log('A')
17  },
18  { target: document }
19)

长按

1import { onLongPress } from '@vueuse/core'
2const el = ref()
3onLongPress(el, () => {
4  console.log('长按500ms')
5})
6
7onLongPress(
8  el,
9  () => {
10    console.log('长按1000ms')
11  },
12  { delay: 1000 }
13)
  • 使用指令
1<script setup lang="ts">
2  import { ref } from 'vue';
3  import { vOnLongPress } from '@vueuse/components';
4</script>
5<template>
6  <button v-on-long-press="onLongPress"></button>
7</template>

设备列表

1import { useDevicesList } from '@vueuse/core'
2const {
3  devices, // 设备列表
4  videoInputs, // 摄像头列表
5  audioInputs, // 麦克风列表
6  audioOutputs, // 扬声器列表
7} = useDevicesList()

屏幕共享

1import { useDisplayMedia } from '@vueuse/core'
2const { isSupported, stream, enabled, start, stop } = useDisplayMedia({
3  enabled: false, // 是否自动调用屏幕共享,false 为手动调用 start 方法
4  video: true, // 屏幕共享
5  audio: true, // 系统音频共享
6})
7
8start()
9
10const video = ref()
11watchEffect(() => {
12  video.srcObject = stream.value
13})

鼠标悬停

1import { useElementHover } from '@vueuse/core'
2const el = ref()
3const isHovered = useElementHover(el)
  • 指令
1import { vElementHover } from '@vueuse/components'
2// <button v-element-hover="onHover">
3//   {{ isHovered }}
4// </button>

焦点

1import { useFocus } from '@vueuse/core'
2
3const el = ref()
4const { focused } = useFocus(el, {
5  initialValue: true, // 是否聚焦后出发元素上的focus事件
6})
7// 设置 focused 会触发聚焦与失焦

地理位置

1import { useGeolocation } from '@vueuse/core'
2const {
3  coords, // 经纬度
4  locatedAt, // 时间
5  error,
6} = useGeolocation()

跟踪用户空闲

1import { useIdle } from '@vueuse/core'
2const { idle, lastActive } = useIdle(5 * 60 * 1000) // 5 min
3console.log(idle.value) // true or false  5 分钟后用户没有做任何操作则为 true

无限滚动

1import { useInfiniteScroll } from '@vueuse/core'
2const el = ref()
3const data = ref([1, 2, 3, 4, 5, 6])
4
5useInfiniteScroll(
6  el,
7  () => {
8    data.value.push(12)
9  },
10  {
11    direction: 'bottom', // 监听方向 "top" | "bottom"
12    distance: 10, // 距离边缘最小距离,默认 0
13  }
14)
  • 指令
1import { vInfiniteScroll } from '@vueuse/components'
2// <div v-infinite-scroll="onLoadMore">
3//   <div v-for="item in data" :key="item">
4//     {{ item }}
5//   </div>
6// </div>
7
8// <!-- with options -->
9// <div v-infinite-scroll="[onLoadMore, { 'distance' : 10 }]">
10//   <div v-for="item in data" :key="item">
11//     {{ item }}
12//   </div>
13// </div>

鼠标位置

1import { useMouse } from '@vueuse/core'
2const { x, y, sourceType } = useMouse()

网络状态

1import { useNetwork } from '@vueuse/core'
2const {
3  isSupported, // 是否支持
4  isOnline, // 是否在线
5  offlineAt, // 上次连接以来的时间
6  downlink, // 下载速度
7  downlinkMax, // 最大可达到的下载速度
8  effectiveType, // 检测到的有效速度类型
9  rtt, // 延迟
10  saveData, // 用户是否激活了数据保护模式
11  type, // 网络类型
12} = useNetwork()
13console.log(isOnline.value)

网络在线

1import { useOnline } from '@vueuse/core'
2const online = useOnline() // 网络是否在线

页面离开

1import { usePageLeave } from '@vueuse/core'
2const isLeft = usePageLeave() // 鼠标是否离开页面

文本选中

1import { useTextSelection } from '@vueuse/core'
2const state = useTextSelection() // state.text