最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

hooks是什么

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

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

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

hooks的優(yōu)點

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

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

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

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

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

2、函數(shù)名/文件名以use開頭,形如: useXX

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

示例如下:

const { nameRef,Fn }= useXX()

hooks和utils區(qū)別

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

異同點:

1.表現(xiàn)形式不同: hooks是在 utils 的基礎(chǔ)上再包一層組件級別的東西(鉤子函數(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)和生命周期方法提取出來,并在多個組件之間共享和重用;utils通常是指一些輔助函數(shù)或工具方法,用于實現(xiàn)一些常見的操作或提供特定功能。

總結(jié):

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

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

hooks和mixin區(qū)別

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

異同點:

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

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

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

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

mixins 的優(yōu)缺點

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

缺點:

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

注:VUE3 提出的 Composition API 旨在解決這些問題。mixins 的缺點是 Composition API 背后的主要動因之一,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)              
      }
  }
}

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

Vue3自定義Hooks是組件下的函數(shù)作用域的,而Vue2時代的Mixins是組件下的全局作用域。全局作用域有時候是不可控的,就像var和let這些變量聲明關(guān)鍵字一樣,const和let是var的修正。Composition Api正是對Vue2時代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ù)龐大會導(dǎo)致下載緩慢哦,請您耐心等待!",
      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();
    // 去除下載對 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:加減計數(shù)(useCount)

useCount函數(shù)封裝:

import { computed, ref, Ref } from "vue"
// 定義hook方法
type CountResultProps = {
    count:Ref<number>;
    multiple:Ref<number>; // 計算屬性
    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ā)點坐標(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ù)通過props接收,先定義參數(shù)類型,內(nèi)部再解構(gòu);

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

寫法2:接收傳參對象,先設(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時代Option Api ,data、methos、watch.....分開寫,這種是碎片化的分散的,代碼一多就容易高耦合,維護(hù)時來回切換代碼是繁瑣的!

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

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

相關(guān)文章

  • vue+axios實現(xiàn)登錄攔截的實例代碼

    vue+axios實現(xiàn)登錄攔截的實例代碼

    本篇文章主要介紹了vue+axios實現(xiàn)登錄攔截的實例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05
  • 基于Vue3實現(xiàn)屏幕音頻捕獲的具體方案

    基于Vue3實現(xiàn)屏幕音頻捕獲的具體方案

    在日常開發(fā)中,我們經(jīng)常會遇到需要錄制音頻的場景,比如在線會議、語音筆記、教學(xué)錄制等,傳統(tǒng)的音頻錄制通常只能捕獲麥克風(fēng)輸入,但在某些場景下,我們可能需要錄制系統(tǒng)音頻,所以本文就來實現(xiàn)一個基于Vue3 Composition API的屏幕音頻捕獲Hook,需要的朋友可以參考下
    2025-11-11
  • Vue3+UmiJS項目中實現(xiàn)WebP圖片自動轉(zhuǎn)換和優(yōu)化

    Vue3+UmiJS項目中實現(xiàn)WebP圖片自動轉(zhuǎn)換和優(yōu)化

    WebP 是一種現(xiàn)代圖片格式,相比傳統(tǒng)的 JPG/PNG 格式,通常可以減少 25-35% 的文件大小,本文將介紹如何在 UmiJS + Vue 3 項目中實現(xiàn) WebP 圖片的自動轉(zhuǎn)換和智能加載,有需要的小伙伴可以了解下
    2025-12-12
  • 前端uniapp微信小程序跨域問題的解決方法

    前端uniapp微信小程序跨域問題的解決方法

    跨域指的是在瀏覽器中,當(dāng)一個網(wǎng)頁嘗試加載另一個不同域名(或協(xié)議、端口號)下的資源時所面臨的限制,這篇文章主要給大家介紹了關(guān)于前端uniapp微信小程序跨域問題的解決方法,需要的朋友可以參考下
    2024-08-08
  • Vue實現(xiàn)動態(tài)樣式的多種方法匯總

    Vue實現(xiàn)動態(tài)樣式的多種方法匯總

    本文要給大家介紹Vue實現(xiàn)動態(tài)樣式的多種方法,下面給大家?guī)韼讉€案列,需要的朋友可以借鑒研究一下。
    2021-06-06
  • vue中手機(jī)號,郵箱正則驗證以及60s發(fā)送驗證碼的實例

    vue中手機(jī)號,郵箱正則驗證以及60s發(fā)送驗證碼的實例

    下面小編就為大家分享一篇vue中手機(jī)號,郵箱正則驗證以及60s發(fā)送驗證碼的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-03-03
  • Vue3中使用mock.js模擬數(shù)據(jù)的示例詳解

    Vue3中使用mock.js模擬數(shù)據(jù)的示例詳解

    前后端同時開發(fā)的時候,后端接口數(shù)據(jù)沒有出來,前端可以使用mock模擬假數(shù)據(jù),所以下面小編就來為大家詳細(xì)介紹一下如何在Vue3中使用mock.js模擬數(shù)據(jù)吧
    2025-03-03
  • vue實現(xiàn)ajax滾動下拉加載,同時具有l(wèi)oading效果(推薦)

    vue實現(xiàn)ajax滾動下拉加載,同時具有l(wèi)oading效果(推薦)

    這篇文章主要介紹了vue實現(xiàn)ajax滾動下拉加載,同時具有l(wèi)oading效果的實現(xiàn)代碼,文章包括難點說明,介紹的非常詳細(xì),感興趣的朋友參考下
    2017-01-01
  • 前端項目常用的三個Skills總結(jié)(Vue、React與UI核心Skills)

    前端項目常用的三個Skills總結(jié)(Vue、React與UI核心Skills)

    最近一種新概念在前端社區(qū)中受到關(guān)注,Skills這個概念很快被React和Vue社區(qū)接受,并引發(fā)了關(guān)于AI編程方式的新思考,這篇文章主要介紹了前端項目常用的三個Skills的相關(guān)資料,分別是Vue、React與UI核心Skills,需要的朋友可以參考下
    2026-05-05
  • Vue中filter使用及根據(jù)id刪除數(shù)組元素方式

    Vue中filter使用及根據(jù)id刪除數(shù)組元素方式

    這篇文章主要介紹了Vue中filter使用及根據(jù)id刪除數(shù)組元素方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03

最新評論

安阳县| 仁怀市| 突泉县| 安溪县| 邛崃市| 普定县| 台前县| 静乐县| 界首市| 鄱阳县| 广宗县| 太白县| 沈丘县| 尼木县| 南京市| 手游| 新闻| 浦江县| 洛隆县| 金塔县| 沂水县| 钟山县| 新丰县| 秀山| 固镇县| 清丰县| 绩溪县| 湖南省| 台山市| 三亚市| 三台县| 称多县| 宝兴县| 石城县| 应城市| 鄂托克旗| 双辽市| 柳林县| 尚志市| 江油市| 青铜峡市|