Vue3 高階 API 大匯總,強(qiáng)到離譜
高階函數(shù)是什么呢?
高階函數(shù)英文名叫:Higher Order function ,一個函數(shù)可以接收一個或多個函數(shù)作為輸入,或者輸出一個函數(shù),至少滿足上述條件之一的函數(shù),叫做高階函數(shù)。
前言
本篇內(nèi)容的知識點比較多,講得不夠細(xì)致,不熟悉的可翻閱前幾篇文章,分別對每個知識點都有一篇特別詳細(xì)的文章。建議讀者收藏!
一、Mixin 混入
mixin 混入,提供了一種非常靈活的方式,來分發(fā) vue 組件中的可復(fù)用功能,一個mixin 對象可以包含任意組件選項,當(dāng)組件使用 mixin 對象時,所有的 mixin 對象的選項將被混入組件本身的選項。
mixins 是一個數(shù)組,一個組件可以引入多個 mixin 對象。使用方法如:
- <script>
- const myMixin = {
- data(){
- return {
- num:520
- }
- },
- mounted(){
- console.log('mixin mounted');
- }
- }
- export default {
- mixins:[myMixin],
- }
- </script>
mixin 使用主要針對選項式API,在vue3中使用相對少。使用時注意事項:
- 使用 mixin 對象時,組件內(nèi)部和 mixin 包含相同選項,該選項會進(jìn)行合并處理,并不會覆蓋。
- 使用的 mixin 對象選項 和實例中的選項擁有相同的屬性時,會選擇就近原則,優(yōu)先繼承實例內(nèi)的值,所以 mixin 對象的屬性會被實例中的屬性給覆蓋掉。
- mixin 對象也可以添加生命周期鉤子函數(shù),兩者都會執(zhí)行,優(yōu)先執(zhí)行 mixin 中的, 然后再執(zhí)行實例中的。
mixin也可以自定義屬性,如果與實例中的屬性沖突時,可以使用 optionMergeStrategies 選項合并策略,自定義合并規(guī)則。
二、自定義指令
自定義指令分為全局和局部自定義指令。
2.1、自定義指令定義
全局自定義指令
在 vue3 中,vue 實例通過createApp 創(chuàng)建,所以全局自定義指令的掛載方式也改變了, directive 被掛載到 app上。
- app.directive('focus',{
- mounted(el){
- el.focus()
- }
- })
局部自定義指令
- const autoFocus = {
- focus:{
- mounted(el){
- el.focus()
- }
- }
- }
- export default{
- directives:autoFocus,
- }
自定義指令 v-xxx 直接使用就好,對應(yīng)上述示例自定義指令為 v-focus。
2.2、自定義指令鉤子函數(shù)參數(shù)
每個鉤子里面的參數(shù)含義:
mounted(el,binding,vnode){…}
el:代表當(dāng)前使用該指令的元素
binding:指令傳來的值
vnode:當(dāng)前元素節(jié)點相關(guān)
2.3、自定義指令鉤子函數(shù)
一個指令定義對象可以提供如下幾個鉤子函數(shù)(都是可選的,根據(jù)需要引入)
- created :綁定元素屬性或事件監(jiān)聽器被應(yīng)用之前調(diào)用。該指令需要附加需要在普通的 v-on 事件監(jiān)聽器前調(diào)用的事件監(jiān)聽器時,這很有用。
- beforeMounted :當(dāng)指令第一次綁定到元素并且在掛載父組件之前執(zhí)行。
- mounted :綁定元素的父組件被掛載之后調(diào)用。
- beforeUpdate :在更新包含組件的 VNode 之前調(diào)用。
- updated :在包含組件的 VNode 及其子組件的 VNode 更新后調(diào)用。
- beforeUnmounted :在卸載綁定元素的父組件之前調(diào)用
- unmounted :當(dāng)指令與元素解除綁定且父組件已卸載時,只調(diào)用一次。
2.4、自定義指令參數(shù)
自定義指令的也可以帶參數(shù),參數(shù)可以是動態(tài)的,參數(shù)可以根據(jù)組件實例數(shù)據(jù)進(jìn)行實時更新。
使用方法如下:
- <template>
- <div>
- <div v-fixed:pos="posData">定位</div>
- </div>
- </template>
- <script>
- //自定義指令動態(tài)參數(shù)
- const autoFocus = {
- fixed:{
- beforeMount(el,binding){
- el.style.position = "fixed"
- el.style.left = binding.value.left+'px'
- el.style.top = binding.value.top + 'px'
- }
- }
- }
- export default {
- directives:autoFocus,
- setup(){
- const posData = {
- left:20,
- top:200
- }
- return {
- posData,
- }
- }
- }
- </script>
三、teleport 傳送門
teleport 傳送門組件,提供一種簡潔的方式,可以指定它里面的內(nèi)容的父元素。通俗易懂地講,就是 teleport 中的內(nèi)容允許我們控制在任意的 DOM 中,使用簡單。
使用語法:
- <teleport to="body">
- <div>
- 需要創(chuàng)建的內(nèi)容
- </div>
- </teleport>
to 屬性是指定 teleport 中的內(nèi)容加入的 DOM 元素。可以是標(biāo)簽名,也可以是 id 或類名。
為什么使用 teleport ?
使用 vue 開發(fā)時,都是在多個組件之間不斷地嵌套,處理元素的樣式或者層級的時候就會變得困難。如我們需要添加一個 modal 模態(tài)框或 toast 提示框,如果我們把這樣的框可以從 vue 組件中剝離出來,我們樣式和層級設(shè)置起來會更加簡便。
有些同學(xué)會想,這直接放到 index.html 中不就好了嗎?另外 modal 、toast 元素需要使用 vue 組件的狀態(tài)值,通過狀態(tài)控制 modal、toast 的隱藏顯示。如果直接放入 index.html 則狀態(tài)控制就復(fù)雜了。
所以 teleport 傳送門組件就派上用場了。有點像“哆啦A夢”的任意門,可以把元素傳送到任意的元素內(nèi)。同時還可以使用 vue 組件內(nèi)的狀態(tài)值控制它。
四、setup
setup 用來寫組合式 api,從生命周期鉤子函數(shù)角度分析,相當(dāng)于取代了 beforeCreate 。會在 creted 之前執(zhí)行。內(nèi)部的屬性和方法,必須 return 暴露出來,將屬性掛載到實例上,否則沒有辦法使用。setup內(nèi)部沒有 this ,所以不能掛載 this 相關(guān)的東西,它可以接收兩個參數(shù):props 和 context 。
setup 特性:
1、這個函數(shù)會在 created 之前執(zhí)行,上述已解釋。
2、setup 內(nèi)部沒有 this,不能掛載 this 相關(guān)的東西。
3、setup 內(nèi)部的屬性和方法,必須 return 暴露出來,否則沒有辦法使用。
4、setup 內(nèi)部數(shù)據(jù)不是響應(yīng)式的。
5、setup不能調(diào)用生命周期相關(guān)函數(shù),但生命周期函數(shù)可以調(diào)用setup內(nèi)的函數(shù)。
五、ref
ref 主要作用是使基礎(chǔ)類的數(shù)據(jù)具備響應(yīng)式能力,使用之前必須引入。在 Composition API中數(shù)據(jù)不具備響應(yīng)式,修改數(shù)據(jù)時視圖不會改變,所以在創(chuàng)建數(shù)據(jù)時,使用ref包裹一下,讓數(shù)據(jù)具備響應(yīng)式。
ref 使用:
- import { ref } from "vue"
- export default{
- setup(){
- let mood = ref("此時心情好差呀!")
- setTimeout(()=>{
- mood.value = "心情要變的像人一樣美"
- },3000)
- return{
- mood
- }
- }
- }
六、reactive
讓引用類型的數(shù)據(jù)具備響應(yīng)式。
與上述的 ref 原理和用法都一致。
- import { reactive } from "vue"
- let me = reactive({
- single:true,
- want:"暖的像火爐的暖男"
- })
七、readonly
讓數(shù)據(jù)只讀,不能修改數(shù)據(jù)。
父子組件之間傳值時,Vue 是單向數(shù)據(jù)流,為了防止子組件修改數(shù)據(jù),所以使用 readonly 包裹數(shù)據(jù),保證只能在源數(shù)據(jù)上修改。
- import { readonly } from "vue"
- let me = readonly({
- single:true,
- want:"要一個對象"
- })
八、toRefs
toRefs 用來解構(gòu) ref、reactive 包裹的響應(yīng)式數(shù)據(jù)。
使用:
- import { ref , reactive, toRefs } from "vue"
- let me = reactive({
- single:true,
- want:"暖的像火爐的暖男"
- })
- const { single, want } = toRefs( me )
九、toRef
父子組件之間進(jìn)行傳值時,有些參數(shù)是可選參數(shù),toRefs 解構(gòu)參數(shù)不存在時就會報錯,使用 toRef 解決該問題。
使用:
- import { toRef } from "vue"
- const love = toRef(obj,'love')
解構(gòu)時先檢查 obj 對象是否存在 love 屬性,如果存在就繼承obj對象中的屬性值,如果不存在就會創(chuàng)建一個。
十、context
setup(props,context)。
context 上下文環(huán)境,其中包括了屬性、插槽、自定義事件三部分。
- setup(props,context){
- const { attrs,slots,emit } = context
- }
attrs 是一個非響應(yīng)式的對象,主要接收 no-props 屬性,經(jīng)常用來傳遞一些樣式屬性。
slots 是一個 proxy 對象,其中 slots.default() 獲取到的是一個數(shù)組,數(shù)組長度由組件的插槽決定,數(shù)組內(nèi)是插槽內(nèi)容。
setup 內(nèi)不存在this,所以 emit 用來替換 之前 this.$emit 的,用于子傳父時,自定義事件觸發(fā)。
十一、watch 新用法
監(jiān)聽數(shù)據(jù)變化,做出相應(yīng)的業(yè)務(wù)處理。在組合式api中,偵聽器可以監(jiān)聽一個或多個屬性,也可以是基礎(chǔ)類型數(shù)據(jù)或引用數(shù)據(jù)類型。
watch 的特點:
- 有惰性:運行的時候,不會立即執(zhí)行。
- 更加具體:需要添加監(jiān)聽的屬性。
- 可以訪問屬性之前的值:回調(diào)函數(shù)內(nèi)會返回最新值和修改之前的值。
- 可配置:可以添加配置項。
配置項
- immediate:配置watch屬性是否立即執(zhí)行,值為 true 時,一旦運行就會立即執(zhí)行,值為false時,保持惰性。
- deep:配置 watch 是否深度監(jiān)聽,值為 true 時,可以監(jiān)聽對象所有屬性,值為 false 時保持更加具體特性,必須指定到具體的屬性上。
十二、watchEffect
是一個幀聽器,也是一個副作用函數(shù)。它會監(jiān)聽引用數(shù)據(jù)類型的所有屬性,不需要具體到某個屬性,一旦運行就會立即監(jiān)聽,組件卸載的時候會停止監(jiān)聽。
watchEffect 特點:
- 非惰性:一旦運行就會立即執(zhí)行。
- 更加抽象:使用時不需要具體指定監(jiān)聽的誰,回調(diào)函數(shù)內(nèi)直接使用就可以。相比watch比較難理解。
- 不可訪問之前的值:只能訪問當(dāng)前最新的值,訪問不到修改之前的值。
watch 的前兩個特點與 watchEffect 的兩個特點剛好相反,watch 通過配置項可以修改成帶有 watchEffect 特點
十三、computed 新用法
在組合式api中計算屬性用法也發(fā)生了改變,使用之前需要引入。
- import { ref, computed } from "vue"
- export default{
- setup(){
- let sum = computed(()=>{
- return ....
- })
- }
- }
也可以是選項式寫法:
- let sum = computed({
- get:()=>{
- return ....
- },
- set:(value)=>{
- return ....
- }
- })
十四、provide / inject
provide發(fā)射數(shù)據(jù)或函數(shù),inject 接收數(shù)據(jù)或函數(shù)。
project / inject 類似與發(fā)布訂閱,主要用在組件傳值層級太深,或兄弟組件沒法傳參,此時使用 project / inject 特別方便。
- //發(fā)射
- import { provide, readonly } from "vue"
- provide('info',readonly(info))
- //接收
- import { inject } from "vue"
- const info = inject('info')
十五、生命周期鉤子函數(shù)新寫法
組合式api中,setup代替了beforeCreated和created,所以這兩個鉤子失效,其他的只需要引入時前面加on即可。
- import { onBeforeMount } from "vue"
- setup(){
- onBeforeMount(()=>{
- ....
- })
- }
其他的鉤子函數(shù)與上相同。

十六、獲取真實DOM
此處的 ref 與上邊的 ref 不同,是獲取真實DOM節(jié)點的函數(shù)。
使用時:
- <div ref="box" class="test" id="boxtest">獲取真實DOM</div>
- import { ref,onMounted } from "vue"
- export default {
- setup(){
- const box = ref(null)
- onMounted(()=>{
- console.log('box',box.value);
- })
- return {
- box
- }
- }
- }
使用的時候記得在return,然后再 mounted 的時候去獲取內(nèi)容就可以了。
































