VueUse使用指北

什么是VueUse

VueUse是一个基于 Composition API 的实用函数集合。通俗的来说,这就是一个工具函数包,它可以帮助你快速实现一些常见的功能,免得你自己去写,解决重复的工作内容。以及进行了基于 Composition API 的封装。让你在 vue3 中更加得心应手。

VueUse有哪些实用程序

总结一下,VueUse中有9种类型的函数:

  1. Animation——包含易于使用的过渡、超时和计时功能。
  2. Browser——可用于不同的屏幕控制、剪贴板、偏好等。
  3. Component——提供了不同组件方法的简写。
  4. Formatters——提供响应时间格式化功能。
  5. Sensors——用来监听不同的DOM事件、输入事件和网络事件。
  6. State——管理用户状态(全局、本地存储、会话存储)。
  7. Utility——不同的实用函数,如 getter、条件、引用同步等。
  8. Watch——更多高级类型的观察器,如可暂停的观察器、退避的观察器和条件观察器。
  9. Misc——不同类型的事件、WebSockets和web workers 的功能

初体验

1
npm i @vueuse/core
1
2
3
4
5
6
7
8
9
10
11
// 在页面中使用
<template>
<div class="wrapper">
<div>鼠标位置: {{ x }}, {{ y }}</div>
</div>
</template>

<script setup>
import { useMouse } from "@vueuse/core";
const { x, y } = useMouse();
</script>

常用函数介绍

useIntervalFn

useIntervalFn可用于实现倒计时功能

参数说明:

第三个参数:immediate: true, immediateCallback: false

immediate 首次运行useIntervalFn函数时,是否立刻开启定时任务(默认值true表示默认开启)

immediateCallback 执行useIntervalFn函数立刻执行回调(在延时时间的前或者后调用),默认值是false,如果修改为true,表示为不延时,立刻启动定时任务(不要使用pause方法)

pause暂停;resume启动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<template>
<div class="wrapper">
<button @click="sendCode">发送验证码</button>
倒计时:{{ timer }}
</div>
</template>

<script setup>
import { useIntervalFn } from "@vueuse/core";
import { ref } from "vue";

const timer = ref(0);
const { pause, resume } = useIntervalFn(
() => {
if (timer.value <= 0) {
// 停止定时任务
pause();
} else {
timer.value--;
}
},
// 每秒执行一次
1000,
{
// 默认不开启定时任务
immediate: false,
}
);

// 发送验证码
const sendCode = () => {
if (timer.value === 0) {
timer.value = 60;
resume();
}
};
</script>

useClipboard

useClipboard实现了复制功能

1
2
3
4
5
6
7
8
9
10
11
12
<template>
<div class="wrapper">
<button @click="copyHandle">复制</button>
<textarea name="" id="" cols="30" rows="10"></textarea>
</div>
</template>

<script setup>
import { useClipboard } from "@vueuse/core";
const { text, copy } = useClipboard();
const copyHandle = () => copy("123123123");
</script>

useCssVar

useCssVar可以用来动态设置css变量,如: var(--color),可以用来配合完成动态主题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<template>
<div class="wrapper">
<div ref="el" style="--color: #7fa998; color: var(--color)">
Sample text, {{ color }}
</div>
<input type="color" @input="changeColor" />
</div>
</template>

<script setup>
import { useCssVar } from "@vueuse/core";
import { ref } from "vue";

const el = ref(null);
const color = useCssVar("--color", el);

const changeColor = (e) => {
console.log(e.target.value);
color.value = e.target.value;
};
</script>

onClickOutside

点击元素外部触发,通常写一些ui组件时会用到该方法,如:弹窗点击外部隐藏

1
2
3
// 目标元素
const target = ref(null);
onClickOutside(target, (event) => console.log("未点中目标元素"));

useToggle

方便的布尔值切换函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<template>
<div class="wrapper">
<p>Value: {{ value ? "ON" : "OFF" }}</p>
<button @click="toggle()">toggle</button>
<button @click="toggle(true)">on</button>
<button @click="toggle(false)">off</button>
</div>
</template>

<script setup>
import { useToggle } from "@vueuse/core";

const [value, toggle] = useToggle();
</script>

useRefHistory

useRefHistory 跟踪对Ref所做的每一个改变,并将其存储在一个数组中。这使我们能够轻松地为我们的应用程序提供撤销和重做功能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<template>
<div class="wrapper">
<input type="text" v-model="text" />
<button :disabled="!canUndo" @click="undo()">撤销</button>
<button :disabled="!canRedo" @click="redo()">还原</button>
<p>历史输入</p>
<ul>
<li v-for="item in history" :key="item.timestamp">{{ item.snapshot }}</li>
</ul>
</div>
</template>

<script setup>
import { useCounter, useRefHistory } from "@vueuse/core";
import { ref } from "vue";
const text = ref("");
const { history, undo, redo, canUndo, canRedo } = useRefHistory(text, {
// 历史数据容量
capacity: 10,
});
</script>

useVModel

封装组件的利器!不用再为了单项数据流的组件封装,而写在组件内写冗余的代码了。
直接将useVModel返回的数据作为响应式对象用即可。

首先创建子组件HelloWorld.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<template>
<div>
<input v-model="NAME" />
</div>
</template>
<script setup>
import { useVModel } from "@vueuse/core";
import { defineProps, defineEmits } from "vue";

const props = defineProps({
name: {
type: String,
required: true,
},
});
const emit = defineEmits(["update:name"]);
const NAME = useVModel(props, `name`, emit);
</script>

在父组件内引用,随着子组件内input输入变化,父组件的_name字段也会同步变化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<template>
<div class="wrapper">
<HelloWorld v-model:name="_name" />

<hr />
组件name字段的值为:{{ _name }}
</div>
</template>

<script setup>
import HelloWorld from "./components/HelloWorld.vue";
import { useCounter, useRefHistory } from "@vueuse/core";
import { ref } from "vue";

const _name = ref("");
</script>

参考资料:
浅谈VueUse设计与实现
【一库】vueuse:我不许身为vuer,你的工具集只有lodash!


VueUse使用指北
https://xypecho.github.io/2022/07/12/VueUse使用指北/
作者
很青的青蛙
发布于
2022年7月12日
许可协议