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