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

vue3.x lodash在項(xiàng)目中管理封裝指令的優(yōu)雅使用

 更新時(shí)間:2023年09月24日 10:21:52   作者:XiaoDaiGua_Ray  
這篇文章主要為大家介紹了vue3.x lodash在項(xiàng)目中管理封裝指令的優(yōu)雅使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

vue3.x directives

vue 指令是一種特殊的 vue.js 特性,用于在 DOM 元素上添加特定的行為或功能。指令通過(guò)在元素上使用特定的指令名稱(chēng)和參數(shù)來(lái)實(shí)現(xiàn),可以用于操作 DOM、響應(yīng)事件、綁定數(shù)據(jù)等。今天簡(jiǎn)述一下如何在項(xiàng)目中優(yōu)雅的管理、封裝一些常用的指令。

后面代碼基本上會(huì)逐行進(jìn)行注釋?zhuān)员阌诖蠹议喿x。

管理指令

統(tǒng)一管理

  • 統(tǒng)一包管理:通過(guò)創(chuàng)建 directives 文件夾,我們可以將所有與指令相關(guān)的文件集中在一個(gè)位置,使其更易于查找和維護(hù)。這種統(tǒng)一的包管理結(jié)構(gòu)有助于組織和管理指令相關(guān)的代碼。
  • 模塊化指令:在 directives/modules 文件夾中,我們?yōu)槊總€(gè)指令創(chuàng)建一個(gè)獨(dú)立的文件夾。這種模塊化的結(jié)構(gòu)使每個(gè)指令的邏輯和功能被封裝在一個(gè)獨(dú)立的文件中,方便單獨(dú)管理和維護(hù)。每個(gè)指令文件夾中的出口文件 index.ts 可以用于導(dǎo)出指令邏輯,使其在項(xiàng)目中得以統(tǒng)一注冊(cè)和使用。
  • 規(guī)范化命名:指令文件夾的命名需要言簡(jiǎn)意賅,能夠清晰表達(dá)指令的用途。通過(guò)規(guī)范化的命名,可以使項(xiàng)目中的指令更易于理解和識(shí)別,提高代碼的可讀性和可維護(hù)性。
  • 可擴(kuò)展性:通過(guò)這種管理方式,我們可以輕松地添加新的指令。只需在 directives/modules 文件夾中創(chuàng)建一個(gè)新的指令文件夾,并在其中編寫(xiě)相應(yīng)的指令邏輯即可。這種結(jié)構(gòu)使項(xiàng)目具有良好的可擴(kuò)展性,方便我們根據(jù)需要添加、修改或刪除指令。
·
├── directives
├──├── index.ts
├──├── modules
├──├──├── some directive
├──├──├──├── index.ts type.ts ...

統(tǒng)一注冊(cè)

每個(gè)指令都使用 index.ts 文件統(tǒng)一暴露一個(gè) CustomDirectiveFC 類(lèi)型的函數(shù),并且在根目錄的 index.ts 中自動(dòng)搜集 modules 文件夾中的所有文件并注冊(cè)這些指令。

公共類(lèi)型(type.ts)

import type { Directive } from 'vue'
import type { App } from 'vue'
export type { DebounceBindingOptions } from './modules/debounce/type'
export type { ThrottleBindingOptions } from './modules/throttle/type'
export type CustomDirectiveFC<T, K> = () => Directive<T, K>
export interface DirectiveModules extends Object {
  default: CustomDirectiveFC<unknown, unknown>
}
export type AppType = App<Element>

搜集、注冊(cè)指令

利用 import.meta.glob 方法(如果是 webpack 則是使用 require.context),獲取所有指令文件夾的路徑。然后,遍歷這些文件夾,找到包含 index.ts 文件的位置。在每個(gè) index.ts 文件中,你可以導(dǎo)入 CustomDirectiveFC 函數(shù)。通過(guò)這種方式,你可以自動(dòng)搜集所有指令,并進(jìn)行注冊(cè)。

警告

該方式會(huì)搜集 modules 中所有的文件夾,并且以文件名稱(chēng)作為指令名稱(chēng)。如果是多個(gè)單詞,請(qǐng)使用小寫(xiě)單詞并以 - 連接。

import type { DirectiveModules, CustomDirectiveFC } from '@/directives/type'
export const combineDirective = <
  T extends Record<string, DirectiveModules>,
  K extends keyof T,
>(
  directiveModules: T,
) => {
  const directives = Object.keys(directiveModules).reduce((pre, curr) => {
    const fc = directiveModules[curr]?.default
    if (typeof fc === 'function') {
      pre[curr] = fc
      return pre
    } else {
      throw new Error('directiveModules[curr] is not function')
    }
  }, {} as Record<K, CustomDirectiveFC<unknown, unknown>>)
  return directives
}
import { combineDirective } from './helper/combine'
import { forIn } from 'lodash-es'
import type { App } from 'vue'
import type { DirectiveModules } from '@/directives/type'
/**
 *
 * 初始化全局自定義指令
 *
 * 該方法會(huì)將 modules 下每個(gè)文件夾視為一個(gè)指令
 * 并且會(huì)將文件夾名稱(chēng)識(shí)別為指令名稱(chēng)
 * 每個(gè)文件下的 index.ts 文件視為每個(gè)指令的入口(也就是指令的處理邏輯, 需要暴露出一個(gè) Directive 類(lèi)型的對(duì)象)
 */
export const setupDirectives = (app: App<Element>) => {
  // 獲取 modules 包下所有的 index.ts 文件
  const directiveRawModules: Record<string, DirectiveModules> =
    import.meta.glob('@/directives/modules/**/index.ts', {
      eager: true,
    })
  // 將所有的包提取出來(lái)(./modules/[file-name]/index.ts)
  const directivesModules = combineDirective(directiveRawModules)
  // 提取文件名(./modules/copy/index.ts => copy)
  const regexExtractDirectiveName = /(?<=modules\/).*(?=\/index\.ts)/
  // 匹配合法指令名稱(chēng)
  const regexDirectiveName = /^([^-]+-)*[^-]+$/
  forIn(directivesModules, (value, key) => {
    const dname = key.match(regexExtractDirectiveName)?.[0]
    if (typeof dname === 'string' && regexDirectiveName.test(dname)) {
      app.directive(dname, value?.())
    } else {
      console.error(`[setupDirectives] ${dname} is not a valid directive name`)
    }
  })
}

在 main.ts 文件中導(dǎo)入并且調(diào)用 setupDirectives 方法,即可完成自定義指令的搜集與注冊(cè)。然后即可在項(xiàng)目全局中使用。

自定義指令

準(zhǔn)備工作我們已經(jīng)完成了,現(xiàn)在只需要開(kāi)發(fā)自定義指令即可?,F(xiàn)在我們來(lái)封裝幾個(gè)常用指令熱熱手。

v-throttle

實(shí)現(xiàn)

import type { ThrottleSettings } from 'lodash-es'
import type { AnyFC } from '@/types/modules/utils'
export interface ThrottleBindingOptions {
  func: AnyFC
  trigger?: string
  wait?: number
  options?: ThrottleSettings
}
import { throttle } from 'lodash-es'
import { on, off } from '@use-utils/element'
import type { ThrottleBindingOptions } from './type'
import type { AnyFC } from '@/types/modules/utils'
import type { DebouncedFunc } from 'lodash-es'
import type { CustomDirectiveFC } from '@/directives/type'
const throttleDirective: CustomDirectiveFC<
  HTMLElement,
  ThrottleBindingOptions
> = () => {
  let throttleFunction: DebouncedFunc<AnyFC> | null
  return {
    beforeMount: (el, { value }) => {
      const { func, trigger = 'click', wait = 500, options } = value
      if (typeof func !== 'function') {
        throw new Error('throttle directive value must be a function')
      }
      throttleFunction = throttle(func, wait, Object.assign({}, options))
      on(el, trigger, throttleFunction)
    },
    beforeUnmount: (el, { value }) => {
      const { trigger = 'click' } = value
      if (throttleFunction) {
        throttleFunction.cancel()
        off(el, trigger, throttleFunction)
      }
      throttleFunction = null
    },
  }
}
export default throttleDirective

使用

<template>
  <p>我執(zhí)行了{(lán){ count }}次</p>
  <p>該方法 1s 內(nèi)僅會(huì)執(zhí)行一次</p>
  <button
    v-throttle="{
      func: handleClick,
      trigger: 'click',
      wait: 1000,
      options: {},
    }"
  >
    節(jié)流按鈕
  </button>
</template>
<script setup lang="ts">
const count = ref(0)
const handleClick = () => {
  count.value++
}
</script>

v-debounce

實(shí)現(xiàn)

import type { DebounceSettings } from 'lodash-es'
import type { AnyFC } from '@/types/modules/utils'
export interface DebounceBindingOptions {
  func: AnyFC
  trigger?: string
  wait?: number
  options?: DebounceSettings
}
import { debounce } from 'lodash-es'
import { on, off } from '@use-utils/element'
import type { DebounceBindingOptions } from './type'
import type { AnyFC } from '@/types/modules/utils'
import type { DebouncedFunc } from 'lodash-es'
import type { CustomDirectiveFC } from '@/directives/type'
const debounceDirective: CustomDirectiveFC<
  HTMLElement,
  DebounceBindingOptions
> = () => {
  let debounceFunction: DebouncedFunc<AnyFC> | null
  return {
    beforeMount: (el, { value }) => {
      const { func, trigger = 'click', wait = 500, options } = value
      if (typeof func !== 'function') {
        throw new Error('debounce directive value must be a function')
      }
      debounceFunction = debounce(func, wait, Object.assign({}, options))
      on(el, trigger, debounceFunction)
    },
    beforeUnmount: (el, { value }) => {
      const { trigger = 'click' } = value
      if (debounceFunction) {
        debounceFunction.cancel()
        off(el, trigger, debounceFunction)
      }
      debounceFunction = null
    },
  }
}
export default debounceDirective

使用

<template>
  <p>我執(zhí)行了{(lán){ count }}次</p>
  <p>該方法將延遲 1s 執(zhí)行</p>
  <button
    v-throttle="{
      func: handleClick,
      trigger: 'click',
      wait: 1000,
      options: {},
    }"
  >
    防抖按鈕
  </button>
</template>
<script setup lang="ts">
const count = ref(0)
const handleClick = () => {
  count.value++
}
</script>

自定義指令目錄結(jié)構(gòu)

·
├── directives
├──├── index.ts type.ts
├──├── modules
├──├──├── throttle
├──├──├──├── index.ts type.ts
├──├──├── debounce
├──├──├──├── index.ts type.ts

按照上述步驟以后,你將會(huì)得到這樣的一個(gè)目錄結(jié)構(gòu)。

最后

所有的代碼源碼都來(lái)自于 Ray Template,可以自行點(diǎn)擊查看源碼

以上就是vue3.x lodash在項(xiàng)目中管理封裝指令的優(yōu)雅使用的詳細(xì)內(nèi)容,更多關(guān)于vue3.x lodash管理封裝指令的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • vue3+luckysheet實(shí)現(xiàn)在線編輯Excel的項(xiàng)目實(shí)踐

    vue3+luckysheet實(shí)現(xiàn)在線編輯Excel的項(xiàng)目實(shí)踐

    本文介紹了使用Luckysheet實(shí)現(xiàn)在線Excel表格功能,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-07-07
  • 解決vscode?Better?Comments插件在vue文件中不顯示相對(duì)應(yīng)的顏色的問(wèn)題

    解決vscode?Better?Comments插件在vue文件中不顯示相對(duì)應(yīng)的顏色的問(wèn)題

    最近使用了Better?Comments這款插件,發(fā)現(xiàn)在ts文件中可以顯示對(duì)應(yīng)的顏色,但在vue文件中并不顯示對(duì)應(yīng)顏色?,下面小編給大家分享解決方法,感興趣的朋友跟隨小編一起看看吧
    2022-09-09
  • Vue3中其他的Composition?API詳解

    Vue3中其他的Composition?API詳解

    這篇文章主要介紹了Vue3中其他的Composition?API,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-03-03
  • Vue CLI 3.x 自動(dòng)部署項(xiàng)目至服務(wù)器的方法

    Vue CLI 3.x 自動(dòng)部署項(xiàng)目至服務(wù)器的方法

    本教程講解的是 Vue-CLI 3.x 腳手架搭建的vue項(xiàng)目, 利用scp2自動(dòng)化部署到靜態(tài)文件服務(wù)器 Nginx。非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2019-04-04
  • vue?el-input設(shè)置必填提示功能(單個(gè)與多個(gè))

    vue?el-input設(shè)置必填提示功能(單個(gè)與多個(gè))

    有的功能需要設(shè)置必填項(xiàng),當(dāng)然也需要判斷是不是添上了,下面這篇文章主要給大家介紹了關(guān)于vue?el-input設(shè)置必填提示功能(單個(gè)與多個(gè))的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-02-02
  • 詳解利用jsx寫(xiě)vue組件的方法示例

    詳解利用jsx寫(xiě)vue組件的方法示例

    這篇文章主要給大家介紹了關(guān)于利用jsx寫(xiě)vue組件的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編來(lái)一起看看吧。
    2017-07-07
  • Vue CLI3基礎(chǔ)學(xué)習(xí)之pages構(gòu)建多頁(yè)應(yīng)用

    Vue CLI3基礎(chǔ)學(xué)習(xí)之pages構(gòu)建多頁(yè)應(yīng)用

    這篇文章主要給大家介紹了關(guān)于Vue CLI3基礎(chǔ)學(xué)習(xí)之pages構(gòu)建多頁(yè)應(yīng)用的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Vue CLI3具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • 詳解Vue中公共組件的封裝

    詳解Vue中公共組件的封裝

    在Vue中,組件是構(gòu)建用戶(hù)界面的基本單位,封裝公共組件是一種良好的實(shí)踐,可以提高代碼的可復(fù)用性和可維護(hù)性,下面我們就來(lái)看看如何封裝一個(gè)公共的按鈕組件吧
    2023-08-08
  • vue-router鉤子函數(shù)實(shí)現(xiàn)路由守衛(wèi)

    vue-router鉤子函數(shù)實(shí)現(xiàn)路由守衛(wèi)

    這篇文章主要介紹了vue-router鉤子函數(shù)實(shí)現(xiàn)路由守衛(wèi),對(duì)vue感興趣的同學(xué),可以參考下
    2021-04-04
  • vue封裝一個(gè)圖案手勢(shì)鎖組件

    vue封裝一個(gè)圖案手勢(shì)鎖組件

    手勢(shì)鎖是常見(jiàn)的一種手機(jī)解鎖方式,本文主要介紹了vue封裝一個(gè)圖案手勢(shì)鎖組件,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-05-05

最新評(píng)論

泰来县| 廉江市| 水富县| 舞阳县| 潜山县| 通河县| 雷波县| 定陶县| 丽水市| 松阳县| 石楼县| 兴化市| 阜城县| 乡宁县| 灵山县| 固阳县| 荔波县| 大冶市| 佛教| 卫辉市| 平遥县| 白玉县| 临海市| 云阳县| 军事| 宿迁市| 开平市| 中宁县| 二连浩特市| 常州市| 广汉市| 永胜县| 隆尧县| 惠安县| 偏关县| 卢龙县| 徐汇区| 邳州市| 高淳县| 隆化县| 青铜峡市|