參考網站
參考網站
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
返回的數據作為響應式對象用即可。
最後
例子太多,就不再一一介紹了,但大家應該已經有了一個初步的概念,知道了此庫的作用,一言以蔽之:助力摸鱼,提前下班。
它沒辦法做到你之前做不到的事情。
它只能做到讓你更輕鬆的完成工作!願你今天也能按時下班。