BACK
Featured image of post 【VueUse】一款基於 Vue Composition API 的函式工具集

【VueUse】一款基於 Vue Composition API 的函式工具集

VueUse 作者為 Anthony Fu,是一個主要以 Composition API 為基底的函式工具庫,封裝了很多常用的功能, 像是追蹤 ref 狀態的更改、鍵盤/滑鼠輸入事件...等實用的功能。

參考網站
參考網站


VueUse 是什麼?

VueUse 作者為 Anthony Fu,是一款基於 Vue 組合式 API (Composition API) 的函數工具集,其中 VueUse 主要特色可以分為以下幾點:

  • Vue 2 和 Vue 3 都支援
  • 採取 Tree Shaking 結構,只會打包引入的程式碼
  • 支持各種套件
  • 可配置事件過濾器和目標

以上是官方網站關於它的定義。

首先,它基於 Vue Composition API (組合式API),只有在支持組合式 API 的環境下,才可以正常使用它。

什麼是組合式 API?

然後,它是一款函數工具集(可類比為 lodash.js / ramda.js)

簡單來說,這是一個能讓你更早下班的工具庫。


VueUse 開源嗎?現狀如何?

當然開源! github/vueuse

社區活躍度:社區非常活躍,截止 2021 年 11 月,一直有 mr 被合入主線。

被引用情況:截止 2021 年 11 月 13 日,npm 上可查詢到依賴它的庫就有 172 個,其中包括著名UI庫:Element-Plus

Vue 的著名開源作者 Evan You 也是此庫的金牌贊助商。


安裝 VueUse

NPM 或 YARN:

1
2
3
npm i @vueuse/core
# or
yarn add @vueuse/core

CDN 引入:

這邊注意 shared 一定要在前面

1
2
<script src="https://unpkg.com/@vueuse/shared"></script>
<script src="https://unpkg.com/@vueuse/core"></script>

注:VueUse 借助 vue-demi 的強大功能,可以在一個包中同時適用於 Vue 2、3!

Vue 3 Demo

Vue 2 Demo (Vue CLI)

另外,要注意庫的版本:

v6.0 版本起,vue3 需要 vue >= v3.2,vue2 需要依賴 @vue/composition-api@vue/composition >= v1.1


VueUse 能做什麼?

能做的那可太多了,但總體上分為以下幾個類別提供工具函數:

  • Animation 動畫
  • Browser 瀏覽器
  • Component 組件
  • Formatters 格式化
  • Sensors 傳感器
  • State 狀態機
  • Utility 實用方法
  • Watch 監聽
  • Misc 各式各樣的雜項

這麼列了一遍,估計你還是很懵,但因為方法實在太多,也不可能一個個都列出來。

那我就舉幾個有代表性的例子,帶你快速理解這些方法大概是做什麼的,有什麼特點。

例子(一):useMouse

1
2
3
4
5
6
7
8
9
<template>
  <div id="app">
    <h3>Mouse: {{x}} x {{y}}</h3>
  </div>
</template>
<script setup lang="ts">
  import { useMouse } from '@vueuse/core'
  const { x, y } = useMouse()
</script>

效果:

Wooooow~~~ 這可太簡單易用了!

經過源碼閱讀,我們可以發現,這短短的一個方法,至少做了以下這些事:

  • 創建了 x 和 y 這兩個響應式對象(Ref)
  • 給 window 添加了鼠標事件監聽,將鼠標的坐標實時賦給 x、y (並且還做了移動端兼容)

如果這些邏輯放到頁面裡,至少需要 6 行代碼,這些代碼後期都會增加維護人員理解頁面的成本,而現在,你只需要一行代碼。

除此之外,該方法還有組件式用法,適合更熱愛標籤的盆友

1
2
3
4
<UseMouse v-slot="{ x, y }">
  x: {{ x }}
  y: {{ y }}
</UseMouse>

例子(二):useInterval

顧名思義,這個方法是對延时重複調用能力的封裝。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<script setup lang="ts">
import { useInterval } from '.'
const { counter, pause, resume } = useInterval(200, { controls: true })

// counter 一個 Ref 對象,它是響應式的,counter.value 等於已經計算的次數
// pause() 暫停
// resume() 恢復 
</script>

<template>
  <div id="APP">
    <p>Interval fired: {{ counter }}</p>
  </div>
</template>

效果:

是不是很好用?相比手寫 setInterval 更為便捷。

如果徒手實現這樣一整套方法,多少行暫且不說,我們需要在業務中寫下大量的邏輯代碼。

而眾所周知:

寫的代碼越多,出 Bug 的可能性越大,維護和理解的難度就越高。從這個角度看,這個庫確實是一個合格的函數工具集。

例子(三):useClipboard

以複製文字為例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<script setup>
  import { useClipboard } from '@vueuse/core'; // 只需要引入所使用到的  API
  import { ref } from 'vue'
  const input = ref('我是 Winnie')
  const { 
  text, // 複製的值
  isSupported, // 瀏覽器有無支援
  copy, // 方法
  copied
  } = useClipboard()
</script>

<template>
<div v-if="isSupported">
  <h3>useClipboard</h3>
  <p>複製內容{{ input }}</p>
  <input v-model="input" />
  <a @click="copy(input)">{{ copied ? "已複製" : "複製" }}</a>
</div>
<p v-else>Your browser does not support Clipboard API</p>
</template>

效果:

例子(四):useVModel

這是一個給經常封裝組件的小伙伴們的大好利器。

先創建一個組件:Test.vue

Test.vue
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<template>
  <div>
    name:
    <input v-model="_name"/>
    age:
    <input v-model="_age"/>
    sex:
    <input v-model="_sex"/>
  </div>
</template>
<script lang="ts" setup>
import { useVModel } from '@vueuse/core'
const props = defineProps({
  name: String,
  age: String,
  sex: String
})
const emit = defineEmits(['update:name', 'update:age', 'update:sex'])

const _name = useVModel(props, 'name', emit)
const _age = useVModel(props, 'age', emit)
const _sex = useVModel(props, 'sex', emit)
</script>

接著,在 index.vue 中使用它

index.vue
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<template>
  <div>
    <Test
    v-model:name="formData.name"
    v-model:age="formData.age"
    v-model:sex="formData.sex"
    ></Test>
    {{ formData }}
  </div>
</template>

<script setup lang="ts">
import { reactive } from 'vue-demi';
import Test from './Test.vue'
const formData = reactive({
  name: 'lily',
  age: '8',
  sex: 'boy'
})
</script>

效果:

對於有組件封裝需求的朋友,這個方法強烈推薦!

不用再為了單向數據流的組件封裝,而在組件內寫冗餘的代碼了。

直接將 useVModel 返回的數據作為響應式對象用即可。


最後

例子太多,就不再一一介紹了,但大家應該已經有了一個初步的概念,知道了此庫的作用,一言以蔽之:助力摸鱼,提前下班

它沒辦法做到你之前做不到的事情。

它只能做到讓你更輕鬆的完成工作!願你今天也能按時下班。


comments powered by Disqus