欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue3自定義Hooks函數(shù)的使用詳解

 更新時(shí)間:2023年09月07日 16:47:49   作者:wdlhao  
vue3 中的 hooks 就是函數(shù)的一種寫法,就是將文件的一些單獨(dú)功能的js代碼進(jìn)行抽離出來(lái)進(jìn)行封裝使用,下面我們就來(lái)看看vue3中自定義Hooks函數(shù)的使用吧

hooks是什么

vue3 中的 hooks 就是函數(shù)的一種寫法,就是將文件的一些單獨(dú)功能的js代碼進(jìn)行抽離出來(lái)進(jìn)行封裝使用。

它的主要作用是Vue3借鑒了React的一種機(jī)制,用于在函數(shù)組件中共享狀態(tài)邏輯和副作用,從而實(shí)現(xiàn)代碼的可復(fù)用性。

注意:其實(shí) hooks 和 vue2 中的 mixin 有點(diǎn)類似,但是相對(duì) mixins 而言, hooks 更清楚復(fù)用功能代碼的來(lái)源, 更清晰易懂。

hooks的優(yōu)點(diǎn)

hooks作為獨(dú)立邏輯的組件封裝,其內(nèi)部的屬性、函數(shù)等和外部組件具有響應(yīng)式依附的作用。

自定義 hook 的作用類似于 vue2 中的 mixin 技術(shù),使用方便,易于上手。

使用 Vue3 的組合 API 封裝的可復(fù)用,高內(nèi)聚低耦合。

自定義hook需要滿足的規(guī)范

1、具備可復(fù)用功能,才需要抽離為hooks獨(dú)立文件

2、函數(shù)名/文件名以u(píng)se開頭,形如: useXX

3、引用時(shí)將響應(yīng)式變量或者方法顯式解構(gòu)暴露出來(lái);

示例如下:

const { nameRef,Fn }= useXX()

hooks和utils區(qū)別

相同點(diǎn): 通過(guò)hooks和utils函數(shù)封裝, 可以實(shí)現(xiàn)組件間共享和復(fù)用,提高代碼的可重用性和可維護(hù)性。

異同點(diǎn):

1.表現(xiàn)形式不同: hooks是在 utils 的基礎(chǔ)上再包一層組件級(jí)別的東西(鉤子函數(shù)等);utils一般用于封裝相應(yīng)的邏輯函數(shù),沒有組件的東西;

2.數(shù)據(jù)是否具有響應(yīng)式: hooks 中如果涉及到 ref,reactive,computed 這些 api 的數(shù)據(jù),是具有響應(yīng)式的;而 utils 只是單純提取公共方法就不具備響應(yīng)式;

3.作用范圍不同: hooks封裝,可以將組件的狀態(tài)和生命周期方法提取出來(lái),并在多個(gè)組件之間共享和重用;utils通常是指一些輔助函數(shù)或工具方法,用于實(shí)現(xiàn)一些常見的操作或提供特定功能。

總結(jié):

utils是通用的工具函數(shù),而hooks是對(duì)utils的一種封裝,用于在組件中共享狀態(tài)邏輯和副作用。

通過(guò)使用hooks,您可以簡(jiǎn)化代碼,并使其更具可讀性和可維護(hù)性。

hooks和mixin區(qū)別

相同點(diǎn): hooks和mixin,都是常用代碼邏輯抽離手段,方便進(jìn)行代碼復(fù)用;

異同點(diǎn):

1. 語(yǔ)法和用法不同: Hooks 是在 Vue 3 的 Composition API 中引入的一種函數(shù)式編程的方式,而 Mixins 是在 Vue 2 中的一種對(duì)象混入機(jī)制。Hooks 使用函數(shù)的方式定義和使用,而 Mixins 則是通過(guò)對(duì)象的方式進(jìn)行定義和應(yīng)用。

2. 組合性和靈活性不同: Hooks 允許開發(fā)者根據(jù)邏輯功能來(lái)組合代碼,封裝為自定義Hook 函數(shù),提高代碼復(fù)用率。而 Mixins 在組件中的屬性和方法會(huì)與組件本身的屬性和方法進(jìn)行合并,可能會(huì)導(dǎo)致命名沖突或不可預(yù)料的行為。

3. 響應(yīng)式系統(tǒng)不同: Vue 3 的 Composition API 使用了一個(gè)新的響應(yīng)式系統(tǒng),可以通過(guò) reactive 和 ref 來(lái)創(chuàng)建響應(yīng)式數(shù)據(jù),可以更精確地控制組件的更新和依賴追蹤。而 Mixins 使用 Vue 2 的響應(yīng)式系統(tǒng),對(duì)數(shù)據(jù)的追蹤和更新較為簡(jiǎn)單,可能存在一些性能上的問(wèn)題。

4. 生命周期鉤子不同: 在 Vue 3 的 Composition API 中,可以使用 onMounted、onUpdated 等鉤子函數(shù)來(lái)替代 Vue 2 中的生命周期鉤子,可以更靈活地管理組件的生命周期。Mixins 依然使用 Vue 2 的生命周期鉤子。

mixins 的優(yōu)缺點(diǎn)

優(yōu)點(diǎn):組件中相同代碼邏輯復(fù)用;

缺點(diǎn):

  • 變量來(lái)源不明確:變量來(lái)源不明確(隱式傳入),不利于閱讀,使代碼變得難以維護(hù)。
  • 命名沖突:多個(gè) mixins 的生命周期會(huì)融合到一起運(yùn)行,但是同名屬性、同名方法無(wú)法融合,可能會(huì)導(dǎo)致沖突。
  • 濫用會(huì)造成維護(hù)問(wèn)題:mixins 和組件可能出現(xiàn)多對(duì)多的關(guān)系,復(fù)雜度較高(即一個(gè)組件可以引用多個(gè) mixins,一個(gè) mixins 也可以被多個(gè)組件引用)。

注:VUE3 提出的 Composition API 旨在解決這些問(wèn)題。mixins 的缺點(diǎn)是 Composition API 背后的主要?jiǎng)右蛑?,Composition API 受到 React Hooks 的啟發(fā)。

hooks代碼:

useCount.ts函數(shù)示例:

import { ref, onMounted, computed } from 'vue';
export default function useCount {
    const count = ref(0);   
    const doubleCount = computed(
      () => count.value * 2
    );
     const increase = (delta) => {
        return count.value + delta;
    }    
    return {
      count,
      doubleCount,
      increase  
    };
}

useCount在組件中調(diào)用:

<script setup lang="ts">
    import useCount from "@/hooks/useCount";
    const { count,doubleCount,increase } = useCount;
    const newCount = increase(10); // 輸出: 10       
</script>

Mixins 的代碼:

export default const countMixin = {
  data() {
    return {
      count: 0
    };
  },
  computed: {
    doubleCount() {
      return this.count * 2;
    }
  },
  methods: {
      increase(delta){
        return this.count + delta;
    }    
};

Mixins在組件中調(diào)用:

import countMixin from '@/mixin/countMixin';
export default {
  mixins: [countMixin],
  mounted() {
    console.log(this.doubleCount);// 輸出: 0
    const newCount = this.setIncrease(10); // 輸出: 10
  },
  methods: {
      setIncrease(count){
        this.increase(count)              
      }
  }
}

這兩個(gè)示例展示了使用 Hooks 和 Mixins 的代碼風(fēng)格和組織方式的不同。Hooks 使用函數(shù)式的方式來(lái)定義邏輯和狀態(tài),而 Mixins 則是通過(guò)對(duì)象的方式進(jìn)行組合和共享代碼。

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

hooks函數(shù)封裝示例

示例1:數(shù)據(jù)導(dǎo)出(useDownload)

useDownload函數(shù)封裝:

import { ElNotification } from "element-plus";
/**
 * @description 接收數(shù)據(jù)流生成 blob,創(chuàng)建鏈接,下載文件
 * @param {any} data 導(dǎo)出的文件blob數(shù)據(jù) (必傳)
 * @param {String} tempName 導(dǎo)出的文件名 (必傳)
 * @param {Boolean} isNotify 是否有導(dǎo)出消息提示 (默認(rèn)為 true)
 * @param {String} fileType 導(dǎo)出的文件格式 (默認(rèn)為.xlsx)
 * */
interface useDownloadParam {
  data: any;
  tempName: string;
  isNotify?: boolean;
  fileType?: string;
}
export const useDownload = async ({ data, tempName,isNotify = true, fileType = ".xlsx" }: useDownloadParam) => {
  if (isNotify) {
    ElNotification({
      title: "溫馨提示",
      message: "如果數(shù)據(jù)龐大會(huì)導(dǎo)致下載緩慢哦,請(qǐng)您耐心等待!",
      type: "info",
      duration: 3000
    });
  }
  try {
    const blob = new Blob([data]);
    // 兼容 edge 不支持 createObjectURL 方法
    if ("msSaveOrOpenBlob" in navigator) return window.navigator.msSaveOrOpenBlob(blob, tempName + fileType);
    const blobUrl = window.URL.createObjectURL(blob);
    const exportFile = document.createElement("a");
    exportFile.style.display = "none";
    exportFile.download = `${tempName}${fileType}`;
    exportFile.href = blobUrl;
    document.body.appendChild(exportFile);
    exportFile.click();
    // 去除下載對(duì) url 的影響
    document.body.removeChild(exportFile);
    window.URL.revokeObjectURL(blobUrl);
  } catch (error) {
    console.log(error);
  }
};

useDownload在組件中使用:

<script setup lang="ts">
import { useDownload } from "@/hooks/useDownload";
const userForm = reactive({})
const userListExport = () => {
    new Promise(resolve => {
        $Request({
            url: $Urls.userListExport,
            method: "post",
            data: userForm,
            responseType: "blob"
        }).then((res: any) => {
            useDownload({
                data: res.data,   
                tempName:"用戶列表"      
            });
            resolve(res);
        });
    });
};
</script>

示例2:加減計(jì)數(shù)(useCount)

useCount函數(shù)封裝:

import { computed, ref, Ref } from "vue"
// 定義hook方法
type CountResultProps = {
    count:Ref<number>;
    multiple:Ref<number>; // 計(jì)算屬性
    increase:(delta?:number)=>void;
    decrease:(delta?:number)=> void;
}
export default function useCount(initValue = 1):CountResultProps{
    const count = ref(initValue)
    const multiple  = computed(
      ()=>count.value * 2
    )
    const increase = (delta?:number):void =>{
        if(typeof delta !== 'undefined'){
            count.value += delta
        }else{
            count.value += 1
        }
    }
    const decrease = (delta?:number):void=>{
        if(typeof delta !== "undefined"){
            count.value -= delta
        }else{
            count.value -= 1
        }
    }
    return {
        count,
        increase,
        decrease,
        multiple
    }
}

useCount函數(shù)在組件中使用:

<template>
   <p>count:{{count}}</p>
   <p>倍數(shù):{{multiple}}</p>
   <div>
     <button @click="increase(1)">加一</button>
     <button @click="decrease(1)">減一</button> // 在模版中直接使用hooks中的方法作為回調(diào)函數(shù)
   </div>
</template>
<script setup lang="ts">
    import useCount from "@/hooks/useCount"
    const {count,multiple,increase,decrease}  = useCount(10)
</script>

示例3:獲取鼠標(biāo)觸發(fā)點(diǎn)坐標(biāo)(useMousePosition)

useMousePosition函數(shù)封裝:

import { ref, onMounted, onUnmounted, Ref } from 'vue'
interface MousePosition {
  x: Ref<number>,
  y: Ref<number>
}
export default function useMousePosition(): MousePosition {
  const x = ref(0)
  const y = ref(0)
  const updateMouse = (e: MouseEvent) => {
    x.value = e.pageX
    y.value = e.pageY
  }
  onMounted(() => {
    document.addEventListener('click', updateMouse)
  })
  onUnmounted(() => {
    document.removeEventListener('click', updateMouse)
  })
  return { x, y }
}

useMousePosition在組件中使用:

<template>
  <div>
    <p>X: {{ x }}</p>
    <p>Y: {{ y }}</p>
  </div>
</template>
<script lang="ts">
    import useMousePosition from '@/hooks/useMousePosition'
    const { x, y } = useMousePosition();
</script>

hooks函數(shù)封裝細(xì)節(jié)歸納

1.hooks函數(shù)接收參數(shù)寫法;

寫法1:參數(shù)通過(guò)props接收,先定義參數(shù)類型,內(nèi)部再解構(gòu);

export function commonRequest(params: Axios.AxiosParams) {
    let {
        url,
        method,
        data,
        responseType = "json",
    } = params;
  }

寫法2:接收傳參對(duì)象,先設(shè)置默認(rèn)值,再定義參數(shù)類型

interface  DeprecationParam {
    from:string;
    replacement:string;
    type:string;
}
export const useDeprecated = (
  { from, replacement,type = 'API' }: DeprecationParam,
) => {}

2.解構(gòu)重命名寫法

// setup中
const { list: goodsList, getList: getGoodsList } = useList(
  axios.get('/url/get/goods')
)
const { list: recommendList, getList: getRecommendList } = useList(
  axios.get('/url/get/recommendGoods')
)

3.KeyboardEvent為鼠標(biāo)按鍵類型

export const useEscapeKeydown = (handler: (e: KeyboardEvent) => void) => {}

總結(jié)

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

Vue3時(shí)代Composition Api,通過(guò)利用各種Hooks和自定義Hooks將碎片化的響應(yīng)式變量和方法按功能分塊寫,實(shí)現(xiàn)高內(nèi)聚低耦合。

到此這篇關(guān)于Vue3自定義Hooks函數(shù)的使用詳解的文章就介紹到這了,更多相關(guān)Vue3 Hooks內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

  • vue 虛擬DOM的原理

    vue 虛擬DOM的原理

    這篇文章主要介紹了vue 虛擬DOM的原理,幫助大家更好的理解和學(xué)習(xí)vue,感興趣的朋友可以了解下
    2020-10-10
  • Vue?3?中?vue-router?的?router.resolve?()?API詳解

    Vue?3?中?vue-router?的?router.resolve?()?API詳解

    router.resolve()?就好比是一個(gè)精準(zhǔn)的?“導(dǎo)航參謀”,當(dāng)我們?cè)?Vue?3?應(yīng)用里需要明確某個(gè)路由地址對(duì)應(yīng)的詳細(xì)信息時(shí),它就能派上用場(chǎng),本文給大家介紹Vue?3?中?vue-router?的?router.resolve?()?API,感興趣的朋友一起看看吧
    2025-04-04
  • vue3 pinia踩坑及解決方案詳解

    vue3 pinia踩坑及解決方案詳解

    這篇文章主要為大家介紹了vue3 pinia踩坑及解決方案詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • Vue項(xiàng)目從webpack3.x升級(jí)webpack4不完全指南

    Vue項(xiàng)目從webpack3.x升級(jí)webpack4不完全指南

    前段時(shí)間,泡面將自己的一個(gè)Vue-cli構(gòu)建的前端框架從webpack3.x升級(jí)到了4.x版本,現(xiàn)在才拉出來(lái)記錄一下,已備忘之用,也和大家分享一下,需要的朋友可以參考下
    2019-04-04
  • vue3?pinia實(shí)現(xiàn)持久化詳解

    vue3?pinia實(shí)現(xiàn)持久化詳解

    Pinia是Vue3的狀態(tài)管理工具,安裝后在入口文件引入,定義store并在組件中使用,本文主要介紹了Vue3中如何使用pinia實(shí)現(xiàn)持久化,需要的可以參考下
    2024-11-11
  • 教你輕松解決Vue?Dialog彈窗詬病

    教你輕松解決Vue?Dialog彈窗詬病

    彈窗經(jīng)常被使用在一些表單的增刪改查啊,或者彈出一些提示信息等等,這篇文章主要給大家介紹了關(guān)于Vue?Dialog彈窗詬病解決的相關(guān)資料,需要的朋友可以參考下
    2023-01-01
  • Vue源碼解析之?dāng)?shù)據(jù)響應(yīng)系統(tǒng)的使用

    Vue源碼解析之?dāng)?shù)據(jù)響應(yīng)系統(tǒng)的使用

    這篇文章主要介紹了Vue源碼解析之?dāng)?shù)據(jù)響應(yīng)系統(tǒng)的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • vue項(xiàng)目中使用lib-flexible解決移動(dòng)端適配的問(wèn)題解決

    vue項(xiàng)目中使用lib-flexible解決移動(dòng)端適配的問(wèn)題解決

    這篇文章主要介紹了vue項(xiàng)目中使用lib-flexible解決移動(dòng)端適配的問(wèn)題解決,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08
  • Element plus實(shí)現(xiàn)圖片手動(dòng)上傳與回顯的過(guò)程

    Element plus實(shí)現(xiàn)圖片手動(dòng)上傳與回顯的過(guò)程

    近期,發(fā)現(xiàn)點(diǎn)擊修改,element ui 的圖片沒有回顯到框中,所以本文給大家介紹了Element plus實(shí)現(xiàn)圖片手動(dòng)上傳與回顯的過(guò)程,文中通過(guò)代碼示例給大家介紹的非常詳細(xì),具有一定的參考價(jià)值,需要的朋友可以參考下
    2024-09-09
  • vue實(shí)現(xiàn)一個(gè)單文件組件的完整過(guò)程記錄

    vue實(shí)現(xiàn)一個(gè)單文件組件的完整過(guò)程記錄

    整個(gè)項(xiàng)目結(jié)構(gòu)清晰,尤其單文件組件的表現(xiàn)力尤為突出,使得每個(gè)組件的邏輯都沒有過(guò)于復(fù)雜,所以這篇文章主要給大家介紹了關(guān)于vue實(shí)現(xiàn)一個(gè)單文件組件的相關(guān)資料,需要的朋友可以參考下
    2021-06-06

最新評(píng)論