作者:Matt Maribojoc
譯者:前端小智
來源:medium
有夢想,有乾貨,微信搜尋 【大遷世界】 關注這個在凌晨還在刷碗的刷碗智。
本文 GitHub https://github.com/qq449245884/xiaozhi 已收錄,有一線大廠面試完整考點、資料以及我的系列文章。
VueUse 是 Anthony Fu 大佬的一個開源專案,它為Vue的開發者提供了大量用於 Vue2 和Vue3 的基本 Composition API 實用工具函式。
它有幾十個用於常見開發人員用例的解決方案,如跟蹤ref
更改,檢測元素可見性,簡化常見Vue模式,鍵盤/滑鼠輸入等。 這是真正節省開發時間的好方法,因為我們不必自己親手新增所有這些標準功能,拿來主義,用就對了(再次感謝大佬的付出)。
我喜歡VueUse庫,因為它在決定提供哪些實用工具時真正把開發者放在第一位,而且它是一個維護良好的庫,因為它與Vue的當前版本保持同步。
VueUse 有哪些實用方法?
如果你想看到每一個實用程式的完整列表,建議去看看官方文件。但總結一下,VueUse 中有9種型別的函式。
- Animation(動畫) - 包含易於使用的過渡、超時和計時功能
- Browser (瀏覽器) - 可以用於不同的螢幕控制元件、剪貼簿、首選項等等
- Component (元件) - 為不同的元件方法提供簡寫
- Sensors (感測器)- 用來監聽不同的DOM事件、輸入事件和網路事件
- State (狀態) - 管理使用者狀態(全域性,本地儲存,會話儲存)
- Utility (實用方法)--不同的實用方法,如
getters
、conditionals
、ref synchronization
等。 - Watch --更高階的觀察器型別,如可暫停的觀察器、放棄的觀察器和條件觀察器
- 其它 - 事件、WebSockets和 Web workers 的不同型別的功能
將 Vueuse 安裝到 Vue 專案中
VueUse 的最大特點之一是,它只用一個包就能相容 Vue2 和 Vue3!
安裝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, 可能通過 window.VueUse
來訪問。
使用 npm,可以通過解構的方式來獲得想要的方法:
import { useRefHistory } from '@vueuse/core'
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
,然後通過 useRefHistory
從 text
中提取history
、undo
和redo
屬性。
import { ref } from 'vue'
import { useRefHistory } from '@vueuse/core'
const text = ref('')
const { history, undo, redo } = useRefHistory(text)
每當我們的ref
發生變化,更新history
屬性時,就會觸發一個監聽器。
為了看看底層做了什麼,我們把 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>
直接,跑起來,效果如下:
還有不同的選項,為這個功能增加更多的功能。例如,我們可以深入追蹤 reactive 物件,並像這樣限制 history
記錄的數量。
const { history, undo, redo } = useRefHistory(text, {
deep: true,
capacity: 10,
})
onClickOutside 關閉 modal
onClickOutside
檢測在一個元素之外的任何點選。根據我的經驗,這個功能最常見的使用情況是關閉任何模態或彈出視窗。
通常,我們希望我們的模態遮蔽網頁的其餘部分,以吸引使用者的注意和限制錯誤。然而,如果他們確實點選了模態之外,我們希望它關閉。
要做到這一點,只有兩個步驟。
- 為要檢測的元素建立一個模板引用
- 使用這個模板
ref
執行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
繫結。這也要求我們的元件接受一個 value
作為 prop,每當這個 value
被修改,我們的元件就會向父類發出一個 update
事件。
useVModel
函式將其簡化為只使用標準的ref
語法。假設我們有一個自定義的文字輸入,試圖為其文字輸入的值建立一個v-model
。通常情況下,我們必須接受一個 value
的 prop,然後發出一個 change
事件來更新父元件中的資料值。
我們可以使用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
時,我們只需呼叫.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 跟蹤元素的可見性
當確定兩個元素是否重疊時,useIntersectionObserver
是非常強大的。這方面的一個很好的用例是檢查一個元素在視口中是否當前可見。
基本上,它檢查目標元素與根元素/文件相交的百分比。如果這個百分比超過了某個閾值,它就會呼叫一個回撥,確定目標元素是否可見。
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
,observer 就會停止,即使我們滾動離開目標元素,我們的值也會保持為 true
。
const { stop } = useIntersectionObserver(
target,
([{ isIntersecting }], observerElement) => {
targetIsVisible.value = isIntersecting
if (isIntersecting) {
stop()
}
},
)
使用 useTransition 做個數字載入動畫
useTransition
是整個VueUse庫中我最喜歡的函式之一。它允許我們只用一行就能順利地在數值之間進行過渡。
如果使用 useTransition
做一個下面這樣的效果,要怎麼做呢?
我們可以通過三個步驟來做到這一點。
- 初始化一個
ref
變數count
,初始值為0
- 使用
useTransition
建立一個變數output
- 改變 count 的值
import { ref } from 'vue'
import { useTransition, TransitionPresets } from '@vueuse/core'
const count = ref(0)
const output = useTransition(count , {
duration: 3000,
transition: TransitionPresets.easeOutExpo,
})
count.value = 5000
</script>
然後在 template 中顯示 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 count = ref(0)
const output = useTransition(count, {
duration: 3000,
transition: TransitionPresets.easeOutExpo,
})
count.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>
總結
這不是VueUse的完整指南。這些只是我平常比較常用的函式,還有很多好用的函式,大家可以自行到官網去學習使用。
~完,我去刷碗了,週末不刷碗,晚上跪榴蓮。
程式碼部署後可能存在的BUG沒法實時知道,事後為了解決這些BUG,花了大量的時間進行log 除錯,這邊順便給大家推薦一個好用的BUG監控工具 Fundebug。
原文:https://learvue.co/2021/07/5-...
交流
有夢想,有乾貨,微信搜尋 【大遷世界】 關注這個在凌晨還在刷碗的刷碗智。
本文 GitHub https://github.com/qq44924588... 已收錄,有一線大廠面試完整考點、資料以及我的系列文章。