5 个可以加速开发的 VueUse 库函数

发布于 2023-11-11 04:25:05 字数 16817 浏览 34 评论 0

VueUse 是 Anthony Fu 的一个开源项目,它为 Vue 开发人员提供了大量适用于 Vue 2 和 Vue 3 的基本 Composition API 实用程序函数。

它有几十个解决方案,适用于常见的开发者用例,如跟踪 Ref 变化、检测元素可见性、简化常见的 Vue 模式、键盘/鼠标输入等。这是一个真正节省开发时间的好方法,因为你不必自己添加所有这些标准功能。

我喜欢 VueUse 库,因为它在决定提供哪些实用工具时真正把开发者放在第一位,而且它是一个维护良好的库,因为它与 Vue 的当前版本保持同步。

VueUse 有哪些实用程序?

如果你想看到每一个实用程序的完整列表,我绝对建议你去看看官方文档[1]。但总结一下,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 的功能

这些类别中的大多数都包含几个不同的功能,所以 VueUse 对于你的使用情况来说是很灵活的,可以作为一个很好的地方来快速开始构建 Vue 应用程序。

在本教程中,我们将看一下 5 个不同的 VueUse 函数,这样你就可以了解在这个库中工作是多么容易。

但首先,让我们将其添加到 Vue 项目中!

将 VueUse 安装到你的 Vue 项目中

VueUse 的最大特点之一是,它只用一个软件包就能同时兼容 Vue 2 和 Vue 3!

安装 VueUse 有两种选择 npm 或 CDN

npm i @vueuse/core # yarn add @vueuse/core
<script src="https://unpkg.com/@vueuse/shared"></script>
<script src="https://unpkg.com/@vueuse/core"></script>

我建议使用 NPM,因为它使用法更容易理解,但如果我们使用 CDN,VueUse 将在应用程序中通过 window.VueUse 访问。

对于 NPM 的安装,所有的功能都可以通过使用标准的对象重构从 @vueuse/core 中导入,像这样访问。

import { useRefHistory } from '@vueuse/core'

好了,现在我们已经安装了 VueUse,让我们在应用程序中使用它!

useRefHistory 跟踪响应式数据的更改

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

让我们看一个示例,其中我们正在构建一个我们希望能够撤消的文本区域。

第一步是在不使用 VueUse 的情况下创建我们的基本组件——使用 ref、textarea 和用于撤消和重做的按钮。

<template>
<p>
<button> Undo </button>
<button> Redo </button>
</p>
<textarea v-model="text"/>
</template>

<script setup>
import { ref } from 'vue'
const text = ref('')
</script>

<style scoped>
button {
border: none;
outline: none;
margin-right: 10px;
background-color: #2ecc71;
color: white;
padding: 5px 10px;;
}
</style>

然后,让我们通过导入 useRefHistory 函数,然后从我们的文本 ref 中提取 history、undo 和 redo 属性来添加 VueUse。这就像调用 useRefHistory 并传递我们的 ref 一样简单。

import { ref } from 'vue'
import { useRefHistory } from '@vueuse/core'

const text = ref('')
const { history, undo, redo } = useRefHistory(text)

每次我们的 ref 更改时,这都会触发一个观察者——更新我们刚刚创建的 history 属性。

然后,为了让我们能真正看到发生了什么,让我们打印出模板内的历史记录,同时在点击相应的按钮时调用我们的 undoredo 函数。

<template>
<p>
<button @click="undo"> Undo </button>
<button @click="redo"> Redo </button>
</p>
<textarea v-model="text"/>
<ul>
<li v-for="entry in history" :key="entry.timestamp">
{{ entry }}
</li>
</ul>
</template>

<script setup>
import { ref } from 'vue'
import { useRefHistory } from '@vueuse/core'
const text = ref('')
const { history, undo, redo } = useRefHistory(text)
</script>

<style scoped>
button {
border: none;
outline: none;
margin-right: 10px;
background-color: #2ecc71;
color: white;
padding: 5px 10px;;
}
</style>

好的,让我们运行它。当我们输入时,每个字符都会触发历史数组中的一个新条目,如果我们点击 undo/redo,我们会转到相应的条目。

还有不同的选项可以为此功能添加更多功能。例如,我们可以深入跟踪反应对象并限制这样的历史条目的数量。

const { history, undo, redo } = useRefHistory(text, {
deep: true,
capacity: 10,
})

有关完整的选项清单,请务必查看文档。

onClickOutside 关闭模态

onClickOutside 检测在一个元素之外的任何点击。根据我的经验,这个功能最常见的使用情况是关闭任何模式或弹出窗口。

通常情况下,我们希望我们的模态挡住网页的其他部分,以吸引用户的注意力并限制错误。然而,如果他们真的点击了模态之外的内容,我们希望它能够关闭。

只需两个步骤即可完成此操作:

  1. 为我们要检测的元素创建一个模板引用
  2. 使用此模板引用运行 onClickOutside

这是一个使用 onClickOutside 的带有弹出窗口的简单组件。

<template>
<button @click="open = true"> Open Popup </button>
<div class="popup" v-if='open'>
<div class="popup-content" ref="popup">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Corporis aliquid autem reiciendis eius accusamus sequi, ipsam corrupti vel laboriosam necessitatibus sit natus vero sint ullam! Omnis commodi eos accusantium illum?
</div>
</div>
</template>

<script setup>
import { ref } from 'vue'
import { onClickOutside } from '@vueuse/core'
const open = ref(false) // state of our popup
const popup = ref() // template ref
// whenever our popup exists, and we click anything BUT it
onClickOutside(popup, () => {
open.value = false
})
</script>

<style scoped>
button {
border: none;
outline: none;
margin-right: 10px;
background-color: #2ecc71;
color: white;
padding: 5px 10px;;
}
.popup {
position: fixed;
top: ;
left: ;
width: 100vw;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: rgba(, , , 0.1);
}
.popup-content {
min-width: 300px;
padding: 20px;
width: 30%;
background: #fff;
}
</style>

结果是这样的,我们可以用我们的按钮打开弹出窗口,然后在弹出内容窗口外点击关闭它。

useVModel 简化了 v-model 绑定

Vue 开发人员的一个常见用例是为组件创建自定义 v-model 绑定。这意味着我们的组件接受一个值作为 prop,并且每当该值被修改时,我们的组件都会向父级发出更新事件。

useVModel 函数将其简化为只使用标准的 ref 语法。假设我们有一个自定义的文本输入,试图为其文本输入的值创建一个 v-model 。通常情况下,我们必须接受一个值的prop,然后emit一个变化事件来更新父组件中的数据值。

我们可以使用 useVModel,把它当作一个普通的 ref,而不是使用 ref 并调用 props.valueupdate:value 。这有助于减少我们需要记住的不同语法的数量!

<template>
<div>
<input
type="text"
:value="data"
@input="update"
/>
</div>
</template>

<script>
import { useVModel } from '@vueuse/core'
export default {
props: ['data'],
setup(props, { emit }) {
const data = useVModel(props, 'data', emit)
console.log(data.value) // equal to props.data
data.value = 'name' // equal to emit('update:data', 'name')
const update = (event) => {
data.value = event.target.value
}
return {
data,
update
}
},
}
</script>

每当我们需要访问我们的值时,我们只需调用 .value ,useVModel 将从我们的组件 props 中给我们提供值。而每当我们改变对象的值时,useVModel 会向父组件发出一个更新事件

下面是一个快速的例子,说明该父级组件可能是什么样子...

<template>
<div>
<p> {{ data }} </p>
<custom-input
:data="data"
@update:data="data = $event"
/>
</div>
</template>

<script>
import CustomInput from './components/CustomInput.vue'
import { ref } from 'vue'
export default {
components: {
CustomInput,
},
setup () {
const data = ref('hello')
return {
data
}
}
}

结果看起来像这样,我们在父级中的值始终与子级中的输入保持同步。

使用 IntersectionObserver 跟踪元素可见性

在确定两个元素是否重叠时,Intersection Observers [2] 非常强大。一个很好的用例是检查元素当前是否在视口中可见。

本质上,它检查目标元素与根元素/文档相交的百分比。如果该百分比超过某个阈值,它会调用一个回调来确定目标元素是否可见。

useIntersectionObserver 提供了一个简单的语法来使用 IntersectionObserver API。我们所需要做的就是为我们想要检查的元素提供一个模板 ref。默认情况下,IntersectionObserver 将以文档的视口为根基,阈值为0.1——所以当这个阈值在任何一个方向被越过时,我们的交集观察器将被触发。

这个例子的代码可能是这样的:我们有一个假的段落,只是在我们的视口中占据了空间,我们的目标元素,然后是一个打印语句,打印我们元素的可见性。

<template>
<p> Is target visible? {{ targetIsVisible }} </p>
<div class="container">
<div class="target" ref="target">
<h1>Hello world</h1>
</div>
</div>
</template>

<script>
import { ref } from 'vue'
import { useIntersectionObserver } from '@vueuse/core'
export default {
setup() {
const target = ref(null)
const targetIsVisible = ref(false)
const { stop } = useIntersectionObserver(
target,
([{ isIntersecting }], observerElement) => {
targetIsVisible.value = isIntersecting
},
)
return {
target,
targetIsVisible,
}
},
}
</script>

<style scoped>
.container {
width: 80%;
margin: auto;
background-color: #fafafa;
max-height: 300px;
overflow: scroll;
}
.target {
margin-top: 500px;
background-color: #1abc9c;
color: white;
padding: 20px;
}
</style>

当我们运行并滚动它时,我们会看到它正确地更新了。

我们还可以为 Intersection Observer 指定更多选项,例如更改其根元素、边距(用于计算交点的根边界框的偏移量)和阈值级别。

const { stop } = useIntersectionObserver(
target,
([{ isIntersecting }], observerElement) => {
targetIsVisible.value = isIntersecting
},
{
// root, rootMargin, threshold, window
// full options in the source: https://github.com/vueuse/vueuse/blob/main/packages/core/useIntersectionObserver/index.ts
threshold: 0.5,
}
)

同样重要的是,这个方法返回一个 stop 函数,我们可以调用这个函数来停止观察交叉点。如果我们只想追踪一个元素在屏幕上第一次可见的时候,这就特别有用。

在这段代码中,一旦 targetIsVisible 被设置为 true ,观察者就会停止,即使我们滚动离开目标元素,我们的值也会保持为 true

const { stop } = useIntersectionObserver(
target,
([{ isIntersecting }], observerElement) => {
targetIsVisible.value = isIntersecting
if (isIntersecting) {
stop()
}
},
)

useTransition 在值之间过渡

useTransition 是整个 veuse 库中我最喜欢的函数之一。它允许我们在一行内平滑地转换数值。

我们有一个存储为 ref 的数字源和一个将在不同数值之间缓和的输出。例如,假设我们想建立一个计数器

我们可以通过三个步骤来做到这一点:

  • 创建我们的 count ref 并将其初始化为零
  • 使用 useTransition 创建 output ref(设置持续时间和转换类型)
  • 更改 count 的值
<script setup>
import { ref } from 'vue'
import { useTransition, TransitionPresets } from '@vueuse/core'

const source = ref(0)

const output = useTransition(source, {
duration: 3000,
transition: TransitionPresets.easeOutExpo,
})

source.value = 5000

</script>

然后,在我们的模板中,我们希望显示 output 的值,因为它可以在不同值之间平滑过渡。

<template>
<h2>
<p> Join over </p>
<p> {{ Math.round(output) }}+ </p>
<p>Developers </p>
</h2>
</template>

<script setup>
import { ref } from 'vue'
import { useTransition, TransitionPresets } from '@vueuse/core'
const source = ref()
const output = useTransition(source, {
duration: 3000,
transition: TransitionPresets.easeOutExpo,
})
source.value = 5000
</script>

这就是结果!

我们还可以使用 useTransition 来过渡整个数字数组,这在处理位置或颜色时很有用。处理颜色的一个绝招是使用一个计算属性将 RGB 值格式化为正确的颜色语法。

<template>
<h2 :style="{ color: color } "> COLOR CHANGING </h2>
</template>

<script setup>
import { ref, computed } from 'vue'
import { useTransition, TransitionPresets } from '@vueuse/core'
const source = ref([, , ])
const output = useTransition(source, {
duration: 3000,
transition: TransitionPresets.easeOutExpo,
})
const color = computed(() => {
const [r, g, b] = output.value
return `rgb(${r}, ${g}, ${b})`
})
source.value = [255, , 255]
</script>

一些进一步定制的酷方法是使用任何内置的过渡预设或使用 CSS 缓动函数来定义我们自己的过渡。

最后的想法

这绝不是 VueUse 的完整指南,这些只是我发现 VueUse 库中最有趣的许多函数。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

文章
评论
29 人气
更多

推荐作者

微信用户

文章 0 评论 0

零度℉

文章 0 评论 0

百度③文鱼

文章 0 评论 0

qq_O3Ao6frw

文章 0 评论 0

Wugswg

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文