Vue3編程流暢技巧自定義Hooks

Vue3自定義Hooks讓寫Vue3更暢快

hook: 直譯[hʊk] 鉤子

Hooks在前端領域並沒有明確定義,借用知乎大佬的定義:在JS裡是callback,事件驅動,集成定義一些可復用的方法。

Vue3官方文檔並沒有對自定義Hooks做任何定義,卻無處不在在使用這個技巧,很多開源項目也在用這個技巧,所以作為一個合格的Vuer學會自定義Hooks讓Composition Api寫起來更豐滿是十分必要的!(飛機-官方文檔在偷偷使用自定義Hooks)

Vue3自定義Hooks定義:

個人理解:一些可復用的方法像鉤子一樣掛著,可以隨時被引入和調用以實現高內聚低耦合的目標,應該都能算是hook;

為什麼Vue3要用自定義Hook?:

結論:就是為瞭讓Compoosition Api更好用更豐滿,讓寫Vue3更暢快!像寫詩一樣寫代碼! 其實這個問題更深意義是為什麼Vue3比Vue2更好!無外呼性能大幅度提升,其實編碼體驗也是Vue3的優點**Composition Api的引入(解決Option Api在代碼量大的情況下的強耦合)** 讓開發者有更好的開發體驗。

個人碎碎念:但是這些所謂的提高開發體驗都是需要開發者不斷學習養成編碼好習慣,同樣是Vue3寫Compoosition Api有的人就能寫得和詩一樣,有的人卻能寫得像💩一樣(衷心希望每個開發者都有一顆對技術熱衷的心,不要為瞭開發而開發,前人寫翔讓後人嘗!抱歉最近因為維護老項目太多感慨)

寫Vue3請擺脫Vue2無腦this的思想:

寫Vue2中很多同學養成瞭 Option Api無腦this的習慣,來到Vue3的Composition Api還是習慣性想用this,更有人為瞭寫this不惜引入getCurrentInstance!這大可不必!

Composition Api的優點之一就是擺脫無腦this導致的強耦合,功能之間互相this,變量和方法在各個方法混雜,無處不在的this是強耦合的,雖然方便,但是碎片化的option api 後期維護是麻煩的。

我相信寫Vue2的同學,一定深有感觸,一個組件下定義大量變和大量方法,方法嵌套方法,方法之間互相共享變量,維護這樣的代碼,看似容易理解的Option Api寫法,我們需要在methos、data、template之間來回切,Option Api這種寫法,代碼量和功能小巧時是十分簡單明瞭的,但是代碼量一多,功能一復雜,我相信review代碼的時候頭都痛。

相對的Composition Api在功能復雜、代碼量巨大的組件下,我們配合自定義Hooks,將代碼通過功能分塊寫,響應變量和方法在一起定義和調用,這樣後期我們改功能A隻需要關註功能A塊下的代碼,不會像Vue2在Option Api需要同時關註methos和data。。。。。

幾張動圖復習Composition Api的好

謝謝 大帥老猿 老師做的動圖,Composition Api VS Option Api 的優缺點十分明瞭展示在瞭動畫上!

Option Api代碼量少還好,代碼量多容易導致高耦合!

說明:上面是Vue2 Option Api的寫法,一個組件下含有data 、methos、computed、watch,同一個功能需要分開寫在這些函數上,如果代碼量少,那看起來似乎十分明瞭清晰。一旦代碼量大功能復雜,各個功能分開寫,維護的時候data 、methos、computed、watch都需要來回切,反而顯得過於分散,又高度耦合。

Composition Api解耦Vue2 Option Api實現低耦合高內聚

說明:如果是Composition Api在功能復雜、代碼量巨大的組件下,我們配合自定義Hook,將代碼按功能分塊寫,變量和方法在一起定義和調用,比如A功能下集成瞭響應式變量和方法,我們後期維護隻需要改動A功能模塊下的代碼,不會像Vue2在Option Api需要同時關註邏輯分散的methos和data。

所以自定義Hook的寫Vue3必須掌握的!它無不體現Vue3 Composition Api 低耦合高內聚的思想! 筆者在看瞭官方文檔和開源的admin模板都是大量使用自定義Hooks的!

定義一下Vue3的自定義Hook:

雖然官方沒有明確指明或定義什麼是自定義Hooks,但是卻無處不在用;

以函數形式抽離一些可復用的方法像鉤子一樣掛著,隨時可以引入和調用,實現高內聚低耦合的目標;

  • 將可復用功能抽離為外部JS文件
  • 函數名/文件名以use開頭,形如:useXX
  • 引用時將響應式變量或者方法顯式解構暴露出來如:const {nameRef,Fn} = useXX()
  • (在setup函數解構出自定義hooks的變量和方法)

實例:

簡單的加減法計算,將加法和減法抽離為2個自定義Hooks,並且相互傳遞響應式數據

  • 加法功能-Hook
import { ref, watch } from 'vue';
const useAdd= ({ num1, num2 })  =>{
    const addNum = ref(0)
    watch([num1, num2], ([num1, num2]) => {
        addFn(num1, num2)
    })
    const addFn = (num1, num2) => {
        addNum.value = num1 + num2
    }
    return {
        addNum,
        addFn
    }
}
export default useAdd
  • 減法功能-Hook
//減法功能-Hook
import { ref, watch } from 'vue';
export function useSub  ({ num1, num2 }){
    const subNum = ref(0)
    watch([num1, num2], ([num1, num2]) => {
        subFn(num1, num2)
    })
    const subFn = (num1, num2) => {
        subNum.value = num1 - num2
    }
    return {
        subNum,
        subFn
    }
}
  • 加減法計算組件
<template>
    <div>
        num1:<input v-model.number="num1" style="width:100px" />
        <br />
        num2:<input v-model.number="num2" style="width:100px" />
    </div>
    <span>加法等於:{{ addNum }}</span>
    <br />
    <span>減法等於:{{ subNum }}</span>
</template>
​
<script setup>
import { ref } from 'vue'
import useAdd from './useAdd.js'     //引入自動hook 
import { useSub } from './useSub.js' //引入自動hook 
​
const num1 = ref(2)
const num2 = ref(1)
//加法功能-自定義Hook(將響應式變量或者方法形式暴露出來)
const { addNum, addFn } = useAdd({ num1, num2 })
addFn(num1.value, num2.value)
//減法功能-自定義Hook (將響應式變量或者方法形式暴露出來)
const { subNum, subFn } = useSub({ num1, num2 })
subFn(num1.value, num2.value)
</script>
​

Vue3自定義Hooks和Vue2時代Mixin關系:

Mixin不足

在 Vue 2 中,mixin 是將部分組件邏輯抽象成可重用塊的主要工具。但是,他們有幾個問題:

1、Mixin 很容易發生沖突:因為每個 mixin 的 property 都被合並到同一個組件中,所以為瞭避免 property 名沖突,你仍然需要瞭解其他每個特性。

2、可重用性是有限的:我們不能向 mixin 傳遞任何參數來改變它的邏輯,這降低瞭它們在抽象邏輯方面的靈活性。

上面這段是Vue3官方文檔的內容,可以概括和補充為:

1、Mixin難以追溯的方法與屬性

Vue3自定義Hooks卻可以

Vue3自定義Hooks, 引用時將響應式變量或者方法顯式暴露出來如:

const {nameRef,Fn} = useXX()

Mixins

export default {
  mixins: [ a, b, c, d, e, f, g ], //一個組件內可以混入各種功能的Mixin
  mounted() {
    console.log(this.name)  //問題來瞭,這個name是來自於哪個mixin?
  }
}

Mixin不明的混淆,我們根本無法獲知屬性來自於哪個Mixin文件,給後期維護帶來困難

Vue3自定義Hooks

//加法功能-自定義Hook(將響應式變量或者方法形式暴露出來)
const { addNum, addFn } = useAdd({ num1, num2 })
addFn(num1.value, num2.value)
//減法功能-自定義Hook (將響應式變量或者方法形式暴露出來)
const { subNum, subFn } = useSub({ num1, num2 })
subFn(num1.value, num2.value)

我們很容易看出每個Hooks顯式暴露出來的響應式變量和方法

2、無法向Mixin傳遞參數來改變邏輯

但是Vue3自定義Hooks卻可以:

Vue3自定義Hooks可以靈活傳遞任何參數來改變它的邏輯,參數不限於其他hook的暴露出來的變量

Mixins

export default {
  mixins: [ addMixin, subMixin], //組件內混入加法和減法Mixin
  mounted(){
      this.add(num1,num2) //調用addMixin內部的add方法
      this.sub(num1,num2) //調用subMixin內部的sub方法
  }  
}

可以通過調用Mixin內部方法來傳遞參數,卻無法直接給Mixin傳遞參數,因為Mixin不是函數形式暴露的,不發傳參

Vue3自定義Hook

在上面實例基礎上添加個算平均的Hook

//平均功能-Hook
import { ref, watch } from "vue";
export function useAverage(addNum) {
  const averageNum = ref(0);
  watch(addNum, (addNum) => {
    averageFn(addNum);
  });
  const averageFn = (addNum) => {
    averageNum.value = addNum / 2;
  };
  return {
    averageNum,
    averageFn,
  };
}

組件內

//組件內
//加法功能-自定義Hook(將響應式變量或者方法形式暴露出來)
const { addNum, addFn } = useAdd({ num1, num2 })
addFn(num1.value, num2.value)//主動調用,返回最新addNum
//平均功能-自定義Hook- hook傳入參數值來其他hook暴露出來的變量
const { averageNum, averageFn} = useAverage(addNum)
averageFn(addNum.value)

Vue3自定義Hooks可以靈活傳遞任何參數來改變它的邏輯,參數不限於其他hook的暴露出來的變量,這提高瞭Vue3在抽象邏輯方面的靈活性。

3、Mixin同名變量會被覆蓋

Vue3自定義Hook可以在引入的時候對同名變量重命名

Mixins

export default {
  mixins: [ addMixin, subMixin], //組件內混入加法和減法Mixin
  mounted(){
      this.add(num1,num2) //調用加法addMixin內部的add方法
      this.sub(num1,num2) //調用減法subMixin內部的sub方法
  }  
}

如果this.add(num1,num2)和 this.sub(num1,num2) 計算的結果返回的同名變量totalNum,由於JS單線程,後面引入的會覆蓋前面的,totalNum最終是減法sub的值

Vue3自定義Hooks

//加法功能-自定義Hook(將響應式變量或者方法形式暴露出來)
const { totalNum:addNum, addFn } = useAdd({ num1, num2 })
addFn(num1.value, num2.value)
//減法功能-自定義Hook (將響應式變量或者方法形式暴露出來)
const { totalNum:subNum, subFn } = useSub({ num1, num2 })
subFn(num1.value, num2.value)

在Vue3自定義Hooks中,雖然加法和減法Hooks都返回瞭totalNum,但是利用ES6對象解構很輕松給變量重命名

總結

Vue2時代Option Api ,data、methos、watch…..分開寫,這種是碎片化的分散的,代碼一多就容易高耦合,維護時來回切換代碼是繁瑣的!

Vue3時代Composition Api,通過利用各種Hooks和自定義Hooks將碎片化的響應式變量和方法按功能分塊寫,實現高內聚低耦合

形象的講法:Vue3自定義Hooks是組件下的函數作用域的,而Vue2時代的Mixins是組件下的全局作用域。全局作用域有時候是不可控的,就像var和let這些變量聲明關鍵字一樣,const和let是var的修正。Composition Api正是對Vue2時代Option Api 高耦合和隨處可見this的黑盒的修正,Vue3自定義Hooks是一種進步。

把Mixin和自定義Hook進行比較,一個是Option Api的體現,一個是Composition Api的體現。如果能理解高內聚低耦合的思想,那麼就能理解為什麼Vue3是使用Composition Api,並通過各種自定義Hooks使代碼更強壯。像寫詩一樣寫代碼。而不是寫屎。

以上就是Vue3編程流暢技巧自定義Hooks的詳細內容,更多關於Vue3編程自定義Hooks的資料請關註WalkonNet其它相關文章!

推薦閱讀: