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

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

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

vue3.x directives

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

后面代碼基本上會逐行進(jìn)行注釋,以便于大家閱讀。

管理指令

統(tǒng)一管理

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

統(tǒng)一注冊

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

公共類型(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>

搜集、注冊指令

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

警告

該方式會搜集 modules 中所有的文件夾,并且以文件名稱作為指令名稱。如果是多個單詞,請使用小寫單詞并以 - 連接。

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'
/**
 *
 * 初始化全局自定義指令
 *
 * 該方法會將 modules 下每個文件夾視為一個指令
 * 并且會將文件夾名稱識別為指令名稱
 * 每個文件下的 index.ts 文件視為每個指令的入口(也就是指令的處理邏輯, 需要暴露出一個 Directive 類型的對象)
 */
export const setupDirectives = (app: App<Element>) => {
  // 獲取 modules 包下所有的 index.ts 文件
  const directiveRawModules: Record<string, DirectiveModules> =
    import.meta.glob('@/directives/modules/**/index.ts', {
      eager: true,
    })
  // 將所有的包提取出來(./modules/[file-name]/index.ts)
  const directivesModules = combineDirective(directiveRawModules)
  // 提取文件名(./modules/copy/index.ts => copy)
  const regexExtractDirectiveName = /(?<=modules\/).*(?=\/index\.ts)/
  // 匹配合法指令名稱
  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 方法,即可完成自定義指令的搜集與注冊。然后即可在項目全局中使用。

自定義指令

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

v-throttle

實現(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)僅會執(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

實現(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

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

最后

所有的代碼源碼都來自于 Ray Template,可以自行點擊查看源碼

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

相關(guān)文章

  • element?ui富文本編輯器的使用效果與步驟(quill-editor)

    element?ui富文本編輯器的使用效果與步驟(quill-editor)

    富文本編輯器在任何項目中都會用到,在Element中我們推薦vue-quill-editor組件,下面這篇文章主要給大家介紹了關(guān)于element?ui富文本編輯器的使用效果與步驟(quill-editor)的相關(guān)資料,需要的朋友可以參考下
    2022-10-10
  • Vue組件通信之父傳子與子傳父詳細(xì)講解

    Vue組件通信之父傳子與子傳父詳細(xì)講解

    這篇文章主要介紹了React中父子組件通信詳解,在父組件中,為子組件添加屬性數(shù)據(jù),即可實現(xiàn)父組件向子組件通信,文章通過圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-10-10
  • vue項目里面引用svg文件并給svg里面的元素賦值

    vue項目里面引用svg文件并給svg里面的元素賦值

    這篇文章主要介紹了vue項目里面引用svg文件并給svg里面的元素賦值,本文分步驟通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-08-08
  • vuejs響應(yīng)用戶事件(如點擊事件)

    vuejs響應(yīng)用戶事件(如點擊事件)

    本篇文章主要介紹了vuejs響應(yīng)用戶事件(如點擊),通過vuejs響應(yīng)用戶事件的技巧,具有一定的參考價值,有興趣的小伙伴們可以參考一下。
    2017-03-03
  • Vue如何實現(xiàn)文件預(yù)覽和下載功能的前端上傳組件

    Vue如何實現(xiàn)文件預(yù)覽和下載功能的前端上傳組件

    在Vue.js項目中,使用ElementUI的el-upload組件可以輕松實現(xiàn)文件上傳功能,通過配置組件參數(shù)和實現(xiàn)相應(yīng)的方法,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-09-09
  • 詳解Vue前端生產(chǎn)環(huán)境發(fā)布配置實戰(zhàn)篇

    詳解Vue前端生產(chǎn)環(huán)境發(fā)布配置實戰(zhàn)篇

    這篇文章主要介紹了詳解Vue前端生產(chǎn)環(huán)境發(fā)布配置實戰(zhàn)篇,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-05-05
  • Vue之版本升級后不兼容的問題及解決過程

    Vue之版本升級后不兼容的問題及解決過程

    本文將探討 Vue 版本升級后常見的不兼容問題,并提供相應(yīng)的解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-03-03
  • vue中多個倒計時實現(xiàn)代碼實例

    vue中多個倒計時實現(xiàn)代碼實例

    這篇文章主要介紹了vue中多個倒計時實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • Vue中$set()的使用方法場景分析

    Vue中$set()的使用方法場景分析

    由于 Vue 會在初始化實例時進(jìn)行雙向數(shù)據(jù)綁定,使用Object.defineProperty()對屬性遍歷添加 getter/setter 方法,所以屬性必須在 data 對象上存在時才能進(jìn)行上述過程 ,這樣才能讓它是響應(yīng)的,這篇文章主要介紹了Vue中$set()的使用方法場景分析,需要的朋友可以參考下
    2023-02-02
  • vue $set 實現(xiàn)給數(shù)組集合對象賦值

    vue $set 實現(xiàn)給數(shù)組集合對象賦值

    這篇文章主要介紹了vue $set 實現(xiàn)給數(shù)組集合對象賦值方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07

最新評論