Vue3編程流暢技巧自定義Hooks
Vue3自定義Hooks讓寫Vue3更暢快
hook: 直譯[h?k] 鉤子
Hooks在前端領(lǐng)域并沒(méi)有明確定義,借用知乎大佬的定義:在JS里是callback,事件驅(qū)動(dòng),集成定義一些可復(fù)用的方法。
Vue3官方文檔并沒(méi)有對(duì)自定義Hooks做任何定義,卻無(wú)處不在在使用這個(gè)技巧,很多開(kāi)源項(xiàng)目也在用這個(gè)技巧,所以作為一個(gè)合格的Vuer學(xué)會(huì)自定義Hooks讓Composition Api寫起來(lái)更豐滿是十分必要的?。?a rel="external nofollow" target="_blank">飛機(jī)-官方文檔在偷偷使用自定義Hooks)
Vue3自定義Hooks定義:
個(gè)人理解:一些可復(fù)用的方法像鉤子一樣掛著,可以隨時(shí)被引入和調(diào)用以實(shí)現(xiàn)高內(nèi)聚低耦合的目標(biāo),應(yīng)該都能算是hook;
為什么Vue3要用自定義Hook?:
結(jié)論:就是為了讓Compoosition Api更好用更豐滿,讓寫Vue3更暢快!像寫詩(shī)一樣寫代碼! 其實(shí)這個(gè)問(wèn)題更深意義是為什么Vue3比Vue2更好!無(wú)外呼性能大幅度提升,其實(shí)編碼體驗(yàn)也是Vue3的優(yōu)點(diǎn)**Composition Api的引入(解決Option Api在代碼量大的情況下的強(qiáng)耦合)** 讓開(kāi)發(fā)者有更好的開(kāi)發(fā)體驗(yàn)。
個(gè)人碎碎念:但是這些所謂的提高開(kāi)發(fā)體驗(yàn)都是需要開(kāi)發(fā)者不斷學(xué)習(xí)養(yǎng)成編碼好習(xí)慣,同樣是Vue3寫Compoosition Api有的人就能寫得和詩(shī)一樣,有的人卻能寫得像??一樣(衷心希望每個(gè)開(kāi)發(fā)者都有一顆對(duì)技術(shù)熱衷的心,不要為了開(kāi)發(fā)而開(kāi)發(fā),前人寫翔讓后人嘗!抱歉最近因?yàn)榫S護(hù)老項(xiàng)目太多感慨)
寫Vue3請(qǐng)擺脫Vue2無(wú)腦this的思想:
寫Vue2中很多同學(xué)養(yǎng)成了 Option Api無(wú)腦this的習(xí)慣,來(lái)到Vue3的Composition Api還是習(xí)慣性想用this,更有人為了寫this不惜引入getCurrentInstance!這大可不必!
Composition Api的優(yōu)點(diǎn)之一就是擺脫無(wú)腦this導(dǎo)致的強(qiáng)耦合,功能之間互相this,變量和方法在各個(gè)方法混雜,無(wú)處不在的this是強(qiáng)耦合的,雖然方便,但是碎片化的option api 后期維護(hù)是麻煩的。
我相信寫Vue2的同學(xué),一定深有感觸,一個(gè)組件下定義大量變和大量方法,方法嵌套方法,方法之間互相共享變量,維護(hù)這樣的代碼,看似容易理解的Option Api寫法,我們需要在methos、data、template之間來(lái)回切,Option Api這種寫法,代碼量和功能小巧時(shí)是十分簡(jiǎn)單明了的,但是代碼量一多,功能一復(fù)雜,我相信review代碼的時(shí)候頭都痛。
相對(duì)的Composition Api在功能復(fù)雜、代碼量巨大的組件下,我們配合自定義Hooks,將代碼通過(guò)功能分塊寫,響應(yīng)變量和方法在一起定義和調(diào)用,這樣后期我們改功能A只需要關(guān)注功能A塊下的代碼,不會(huì)像Vue2在Option Api需要同時(shí)關(guān)注methos和data。。。。。
幾張動(dòng)圖復(fù)習(xí)Composition Api的好
謝謝 大帥老猿 老師做的動(dòng)圖,Composition Api VS Option Api 的優(yōu)缺點(diǎn)十分明了展示在了動(dòng)畫上!
Option Api代碼量少還好,代碼量多容易導(dǎo)致高耦合!
說(shuō)明:上面是Vue2 Option Api的寫法,一個(gè)組件下含有data 、methos、computed、watch,同一個(gè)功能需要分開(kāi)寫在這些函數(shù)上,如果代碼量少,那看起來(lái)似乎十分明了清晰。一旦代碼量大功能復(fù)雜,各個(gè)功能分開(kāi)寫,維護(hù)的時(shí)候data 、methos、computed、watch都需要來(lái)回切,反而顯得過(guò)于分散,又高度耦合。
Composition Api解耦Vue2 Option Api實(shí)現(xiàn)低耦合高內(nèi)聚
說(shuō)明:如果是Composition Api在功能復(fù)雜、代碼量巨大的組件下,我們配合自定義Hook,將代碼按功能分塊寫,變量和方法在一起定義和調(diào)用,比如A功能下集成了響應(yīng)式變量和方法,我們后期維護(hù)只需要改動(dòng)A功能模塊下的代碼,不會(huì)像Vue2在Option Api需要同時(shí)關(guān)注邏輯分散的methos和data。
所以自定義Hook的寫Vue3必須掌握的!它無(wú)不體現(xiàn)Vue3 Composition Api 低耦合高內(nèi)聚的思想! 筆者在看了官方文檔和開(kāi)源的admin模板都是大量使用自定義Hooks的!
定義一下Vue3的自定義Hook:
雖然官方?jīng)]有明確指明或定義什么是自定義Hooks,但是卻無(wú)處不在用;
以函數(shù)形式抽離一些可復(fù)用的方法像鉤子一樣掛著,隨時(shí)可以引入和調(diào)用,實(shí)現(xiàn)高內(nèi)聚低耦合的目標(biāo);
- 將可復(fù)用功能抽離為外部JS文件
- 函數(shù)名/文件名以u(píng)se開(kāi)頭,形如:useXX
- 引用時(shí)將響應(yīng)式變量或者方法顯式解構(gòu)暴露出來(lái)如:const {nameRef,F(xiàn)n} = useXX()
- (在setup函數(shù)解構(gòu)出自定義hooks的變量和方法)
實(shí)例:
簡(jiǎn)單的加減法計(jì)算,將加法和減法抽離為2個(gè)自定義Hooks,并且相互傳遞響應(yīng)式數(shù)據(jù)
- 加法功能-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 } }
- 加減法計(jì)算組件
<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' //引入自動(dòng)hook import { useSub } from './useSub.js' //引入自動(dòng)hook ? const num1 = ref(2) const num2 = ref(1) //加法功能-自定義Hook(將響應(yīng)式變量或者方法形式暴露出來(lái)) const { addNum, addFn } = useAdd({ num1, num2 }) addFn(num1.value, num2.value) //減法功能-自定義Hook (將響應(yīng)式變量或者方法形式暴露出來(lái)) const { subNum, subFn } = useSub({ num1, num2 }) subFn(num1.value, num2.value) </script> ?
Vue3自定義Hooks和Vue2時(shí)代Mixin關(guān)系:
Mixin不足
在 Vue 2 中,mixin 是將部分組件邏輯抽象成可重用塊的主要工具。但是,他們有幾個(gè)問(wèn)題:
1、Mixin 很容易發(fā)生沖突:因?yàn)槊總€(gè) mixin 的 property 都被合并到同一個(gè)組件中,所以為了避免 property 名沖突,你仍然需要了解其他每個(gè)特性。
2、可重用性是有限的:我們不能向 mixin 傳遞任何參數(shù)來(lái)改變它的邏輯,這降低了它們?cè)诔橄筮壿嫹矫娴撵`活性。
上面這段是Vue3官方文檔的內(nèi)容,可以概括和補(bǔ)充為:
1、Mixin難以追溯的方法與屬性
Vue3自定義Hooks卻可以
Vue3自定義Hooks, 引用時(shí)將響應(yīng)式變量或者方法顯式暴露出來(lái)如:
const {nameRef,F(xiàn)n} = useXX()
Mixins
export default { mixins: [ a, b, c, d, e, f, g ], //一個(gè)組件內(nèi)可以混入各種功能的Mixin mounted() { console.log(this.name) //問(wèn)題來(lái)了,這個(gè)name是來(lái)自于哪個(gè)mixin? } }
Mixin不明的混淆,我們根本無(wú)法獲知屬性來(lái)自于哪個(gè)Mixin文件,給后期維護(hù)帶來(lái)困難
Vue3自定義Hooks
//加法功能-自定義Hook(將響應(yīng)式變量或者方法形式暴露出來(lái)) const { addNum, addFn } = useAdd({ num1, num2 }) addFn(num1.value, num2.value) //減法功能-自定義Hook (將響應(yīng)式變量或者方法形式暴露出來(lái)) const { subNum, subFn } = useSub({ num1, num2 }) subFn(num1.value, num2.value)
我們很容易看出每個(gè)Hooks顯式暴露出來(lái)的響應(yīng)式變量和方法
2、無(wú)法向Mixin傳遞參數(shù)來(lái)改變邏輯
但是Vue3自定義Hooks卻可以:
Vue3自定義Hooks可以靈活傳遞任何參數(shù)來(lái)改變它的邏輯,參數(shù)不限于其他hook的暴露出來(lái)的變量
Mixins
export default { mixins: [ addMixin, subMixin], //組件內(nèi)混入加法和減法Mixin mounted(){ this.add(num1,num2) //調(diào)用addMixin內(nèi)部的add方法 this.sub(num1,num2) //調(diào)用subMixin內(nèi)部的sub方法 } }
可以通過(guò)調(diào)用Mixin內(nèi)部方法來(lái)傳遞參數(shù),卻無(wú)法直接給Mixin傳遞參數(shù),因?yàn)镸ixin不是函數(shù)形式暴露的,不發(fā)傳參
Vue3自定義Hook
在上面實(shí)例基礎(chǔ)上添加個(gè)算平均的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, }; }
組件內(nèi)
//組件內(nèi) //加法功能-自定義Hook(將響應(yīng)式變量或者方法形式暴露出來(lái)) const { addNum, addFn } = useAdd({ num1, num2 }) addFn(num1.value, num2.value)//主動(dòng)調(diào)用,返回最新addNum //平均功能-自定義Hook- hook傳入?yún)?shù)值來(lái)其他hook暴露出來(lái)的變量 const { averageNum, averageFn} = useAverage(addNum) averageFn(addNum.value)
Vue3自定義Hooks可以靈活傳遞任何參數(shù)來(lái)改變它的邏輯,參數(shù)不限于其他hook的暴露出來(lái)的變量,這提高了Vue3在抽象邏輯方面的靈活性。
3、Mixin同名變量會(huì)被覆蓋
Vue3自定義Hook可以在引入的時(shí)候?qū)ν兞恐孛?/p>
Mixins
export default { mixins: [ addMixin, subMixin], //組件內(nèi)混入加法和減法Mixin mounted(){ this.add(num1,num2) //調(diào)用加法addMixin內(nèi)部的add方法 this.sub(num1,num2) //調(diào)用減法subMixin內(nèi)部的sub方法 } }
如果this.add(num1,num2)和 this.sub(num1,num2) 計(jì)算的結(jié)果返回的同名變量totalNum,由于JS單線程,后面引入的會(huì)覆蓋前面的,totalNum最終是減法sub的值
Vue3自定義Hooks
//加法功能-自定義Hook(將響應(yīng)式變量或者方法形式暴露出來(lái)) const { totalNum:addNum, addFn } = useAdd({ num1, num2 }) addFn(num1.value, num2.value) //減法功能-自定義Hook (將響應(yīng)式變量或者方法形式暴露出來(lái)) const { totalNum:subNum, subFn } = useSub({ num1, num2 }) subFn(num1.value, num2.value)
在Vue3自定義Hooks中,雖然加法和減法Hooks都返回了totalNum,但是利用ES6對(duì)象解構(gòu)很輕松給變量重命名
總結(jié)
Vue2時(shí)代Option Api ,data、methos、watch.....分開(kāi)寫,這種是碎片化的分散的,代碼一多就容易高耦合,維護(hù)時(shí)來(lái)回切換代碼是繁瑣的!
Vue3時(shí)代Composition Api,通過(guò)利用各種Hooks和自定義Hooks將碎片化的響應(yīng)式變量和方法按功能分塊寫,實(shí)現(xiàn)高內(nèi)聚低耦合
形象的講法:Vue3自定義Hooks是組件下的函數(shù)作用域的,而Vue2時(shí)代的Mixins是組件下的全局作用域。全局作用域有時(shí)候是不可控的,就像var和let這些變量聲明關(guān)鍵字一樣,const和let是var的修正。Composition Api正是對(duì)Vue2時(shí)代Option Api 高耦合和隨處可見(jiàn)this的黑盒的修正,Vue3自定義Hooks是一種進(jìn)步。
把Mixin和自定義Hook進(jìn)行比較,一個(gè)是Option Api的體現(xiàn),一個(gè)是Composition Api的體現(xiàn)。如果能理解高內(nèi)聚低耦合的思想,那么就能理解為什么Vue3是使用Composition Api,并通過(guò)各種自定義Hooks使代碼更強(qiáng)壯。像寫詩(shī)一樣寫代碼。而不是寫屎。
以上就是Vue3編程流暢技巧自定義Hooks的詳細(xì)內(nèi)容,更多關(guān)于Vue3編程自定義Hooks的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
vue環(huán)形進(jìn)度條組件實(shí)例應(yīng)用
在本文中我們給大家分享了關(guān)于vue環(huán)形進(jìn)度條組件的使用方法以及實(shí)例代碼,需要的朋友們跟著測(cè)試下吧。2018-10-10vue項(xiàng)目中使用ueditor的實(shí)例講解
下面小編就為大家分享一篇vue項(xiàng)目中使用ueditor的實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-03-03淺談vue+webpack項(xiàng)目調(diào)試方法步驟
本篇文章主要介紹了淺談vue+webpack項(xiàng)目調(diào)試方法步驟,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-09-09Vue3之getCurrentInstance與ts結(jié)合使用的方式
這篇文章主要介紹了Vue3之getCurrentInstance與ts結(jié)合使用的方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04Vuex中this.$store.commit()和this.$store.dispatch()區(qū)別說(shuō)明
這篇文章主要介紹了Vuex中this.$store.commit()和this.$store.dispatch()區(qū)別說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-04-04vue實(shí)現(xiàn)商品購(gòu)物車全選反選
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)商品購(gòu)物車全選反選,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04