VueUse 是 Anthony Fu 的一个开源项目,它为 Vue 开发人员提供了大量适用于 Vue 2 和 Vue 3 的基本 Composition API 实用程序函数。javascript
它有几十个解决方案,适用于常见的开发者用例,如跟踪Ref变化、检测元素可见性、简化常见的Vue模式、键盘/鼠标输入等。这是一个真正节省开发时间的好方法,由于你没必要本身添加全部这些标准功能。css
我喜欢VueUse库,由于它在决定提供哪些实用工具时真正把开发者放在第一位,并且它是一个维护良好的库,由于它与Vue的当前版本保持同步。html
若是你想看到每个实用程序的完整列表,我绝对建议你去看看官方文档。但总结一下,VueUse中有9种类型的函数。vue
这些类别中的大多数都包含几个不一样的功能,因此VueUse对于你的使用状况来讲是很灵活的,能够做为一个很好的地方来快速开始构建Vue应用程序。java
在本教程中,咱们将看一下5个不一样的VueUse函数,这样你就能够了解在这个库中工做是多么容易。ios
但首先,让咱们将其添加到Vue项目中!git
VueUse的最大特色之一是,它只用一个软件包就能同时兼容Vue 2和Vue 3!github
安装VueUse有两种选择npm或CDNweb
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
对于NPM的安装,全部的功能均可以经过使用标准的对象重构从 @vueuse/core
中导入,像这样访问。
import { useRefHistory } from '@vueuse/core'
复制代码
好了,如今咱们已经安装了VueUse,让咱们在应用程序中使用它!
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
属性。
而后,为了让咱们能真正看到发生了什么,让咱们打印出模板内的历史记录,同时在点击相应的按钮时调用咱们的 undo
和 redo
函数。
<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
的带有弹出窗口的简单组件。
<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>
复制代码
结果是这样的,咱们能够用咱们的按钮打开弹出窗口,而后在弹出内容窗口外点击关闭它。
Vue 开发人员的一个常见用例是为组件建立自定义 v-model 绑定。这意味着咱们的组件接受一个值做为 prop,而且每当该值被修改时,咱们的组件都会向父级发出更新事件。
useVModel函数将其简化为只使用标准的 ref
语法。假设咱们有一个自定义的文本输入,试图为其文本输入的值建立一个 v-model
。 一般状况下,咱们必须接受一个值的prop,而后emit一个变化事件来更新父组件中的数据值。
咱们可使用useVModel,把它看成一个普通的ref,而不是使用ref并调用 props.value
和 update: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 } } } 复制代码
结果看起来像这样,咱们在父级中的值始终与子级中的输入保持同步。
在肯定两个元素是否重叠时,Intersection Observers 很是强大。一个很好的用例是检查元素当前是否在视口中可见。
本质上,它检查目标元素与根元素/文档相交的百分比。若是该百分比超过某个阈值,它会调用一个回调来肯定目标元素是否可见。
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
是整个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 库中最有趣的许多函数。
我喜欢全部这些实用功能对加快开发速度的帮助,由于它们中的每个都是为了解决具体而又常见的用例。
原文:learnvue.co ,做者:Matt Maribojoc