vue3自定義hooks/可組合函數(shù)方式
自定義hooks/可組合函數(shù)
vue3 composition api下mixins的替代方式(自定義hooks / 可組合函數(shù))
傳統(tǒng)方式下封裝的mixins在引入文件里都是通過this來調(diào)用屬性或方法,
而在vue3的composition API下this是undefined,實際上這兩者就是沖突的,
只能封裝一套全新的方式來使用類似mixins的功能。
我們稱這種全新的方式為自定義hooks(注:寫這篇文章時vue官方還沒有這個概念,基本靠自己摸索,參照react的習(xí)慣而稱之為自定義hooks,現(xiàn)在已經(jīng)有了官方定義:可組合函數(shù))。
1.mixins方式的痛點
傳統(tǒng)的mixins有很多讓人詬病的地方,mixins 的深度合并非常隱式,這讓代碼邏輯更難理解和調(diào)試,具體表現(xiàn)為如下幾點:
- mixins 容易沖突:因為每個特性的屬性都被合并到同一個組件中,組件內(nèi)同名的屬性或方法會把mixins里的覆蓋掉。
- 可重用性有限:我們不能向 mixins 傳遞任何參數(shù)來改變它的邏輯,這降低了它們在抽象邏輯方面的靈活性。
- 數(shù)據(jù)來源不清晰:組件里所使用的mixins里的數(shù)據(jù)或方法在當(dāng)前組件代碼里搜索不到,易造成錯誤的解讀,比如被當(dāng)成錯誤代碼或冗余代碼而誤刪。
2.傳統(tǒng)mixins方式示例
myMixins.ts:
export default { ? data () { ? ? return { ? ? ? aa: 1 ? ? } ? }, ? mounted () { ? ? this.testFn() ? }, ? methods: { ? ? testFn () { ? ? ? console.log('testFn') ? ? } ? } }
index.vue:
<template> ? <div>{{ aa }}</div> </template> <script lang="ts"> import { defineComponent, onMounted } from 'vue' import myMixins from './myMixins' export default defineComponent({ ? mixins: [myMixins], ? mounted () { ? ? console.log('index mounted') ? } }) </script>
如上所示,封裝的myMixins實際上只做了兩件事,一是在mounted鉤子函數(shù)里執(zhí)行testFn方法,二是暴露一個aa的變量給外部使用;index.vue里引入后在dom里使用了aa。
這算是mixins最典型的兩個用途,一是自己執(zhí)行一些公共邏輯,外部引入時不用管,二是定義一些data變量給外部引入后使用。
3.自定義hooks方式示例
1、代碼封裝
先上代碼,myHooks.ts:
import { ref, onMounted } from 'vue' export default function () { ? const aa = ref(1) ? function testFn () { ? ? console.log('testFn') ? } ? onMounted(() => { ? ? testFn() ? }) ? return { ? ? aa ? } }
index.vue:
<template> ? <div>{{ aa }}</div> </template> <script lang="ts"> import { defineComponent, onMounted } from 'vue' import myHooks from './myHooks' export default defineComponent({ ? setup () { ? ? const { aa } = myHooks() ? ? onMounted(() => { ? ? ? console.log('index mounted') ? ? }) ? ? return { ? ? ? aa ? ? } ? } }) </script>
可以看到,這里沒有再使用mixins屬性來引入邏輯代碼,本質(zhì)上只是封裝了一個ts文件引入使用而已,這樣使用后,數(shù)據(jù)來源清晰可見,代碼引用有依有據(jù)。
2、為什么導(dǎo)出的是function
因為導(dǎo)出為對象的話就意味著在import導(dǎo)入時就執(zhí)行了封裝的邏輯,而我們封裝的邏輯是用composition api包裝了的的特殊代碼,這些代碼只能在setup里才能正常使用,所以需要導(dǎo)出一個函數(shù),這樣就可以在組件
setup里調(diào)用該函數(shù)來指定執(zhí)行時機。
導(dǎo)出為function還有一個用途是方便傳參,這樣可以在不同的組件引用時做一些差異化邏輯處理。
3、封裝建議
導(dǎo)出的function只需要return組件里要引用的數(shù)據(jù);對于組件里不需要引用的就不需要return,組件里只調(diào)用導(dǎo)入的函數(shù)即可。
組件里的自定義hooks調(diào)用代碼最好放在setup里第一行位置,這樣比較明確,不容易被遺漏。
響應(yīng)式api的使用風(fēng)格保持統(tǒng)一,其實這也是整個項目風(fēng)格統(tǒng)一的問題,對于setup里定義的數(shù)據(jù)做響應(yīng)式處理,要么都用ref,要么都用reative,保持統(tǒng)一,這樣在使用時不至于有的帶.value有的不帶。
vue3(hooks)
vue3的hooks相當(dāng)于是封裝公共方法的js文件
/**計數(shù)器+-方法的hooks文件**/ import { ref } from 'vue' export default function() { ? ? const counter = ref(0) ? ? const increment = () => { ? ? ? ? counter.value++ ? ? } ? ? const devrement = () => { ? ? ? ? counter.value-- ? ? } ? ? ? return { ? ? ? ? counter, ? ? ? ? increment, ? ? ? ? devrement ? ? } }
引入以及使用方法如下
<template> ? ? <div> ? ? ? ? <h1>我的名字是:{{info.name}}</h1> ? ? ? ? <h1>我的年齡是:{{info.age}}</h1> ? ? ? ? <h1>當(dāng)前計數(shù)為:{{counter}}</h1> ? ? ? ? <button @click="increment">點擊加一</button> ? ? ? ? <button @click="devrement">點擊減一</button> ? ? </div> </template>
<script> ?//這里也可以使用setup語法糖寫法 import { reactive } from 'vue'; //引入hooks文件 文件名當(dāng)作變量名 import useCounter from '../hooks/useCounter.js'; export default { ? ? setup(){ ? ? ? ? const info = reactive({name:'dxx',age:18}) ? ? ? ? //將hooks文件里的方法和變量全部解構(gòu)出來使用 ? ? ? ? const { counter, increment, devrement } = useCounter() ? ? ? ? //最后將方法和變量導(dǎo)出 ? ? ? ? return { ? ? ? ? ? ? info, ? ? ? ? ? ? counter, ? ? ? ? ? ? increment, ? ? ? ? ? ? devrement ? ? ? ? } ? ? } } </script>
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Vue實現(xiàn)數(shù)據(jù)導(dǎo)入的四種方法(resource、Axios、Fetch、Excel導(dǎo)入)
本文主要介紹了Vue實現(xiàn)數(shù)據(jù)導(dǎo)入的四種方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07vue實現(xiàn)錄音功能js-audio-recorder帶波浪圖效果的示例
這篇文章主要介紹了vue實現(xiàn)錄音功能js-audio-recorder帶波浪圖效果,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-08-08關(guān)于el-form表單驗證中的validator與validate使用時的問題
這篇文章主要介紹了關(guān)于el-form表單驗證中的validator與validate使用時的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-06-06el-select 數(shù)據(jù)回顯,只顯示value不顯示lable問題
這篇文章主要介紹了el-select 數(shù)據(jù)回顯,只顯示value不顯示lable問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-09-09