Vue 3 顯著增強了自定義指令的功能,使其封裝更加靈活和易用。本文將分為基礎和進階兩部分,介紹如何實現常用的自定義指令,并提供最佳的項目組織方式。
前言
-
本文以復制文本的自定義指令詳細介紹自定義指令的基礎知識
-
多個自定義指令如何進行代碼及目錄的組織
-
如何更好的進行方法抽離使公共方法和自定義指令進行解耦
-
自定義指令的高階用法
1. 指令生命周期
Vue 3 自定義指令的生命周期如下:
-
created
:指令綁定到元素上時調用,且只調用一次。 -
beforeMount
:在元素插入 DOM 之前調用。 -
mounted
:元素插入 DOM 后調用。 -
beforeUpdate
:更新包含綁定值的元素時調用,發生在更新前。 -
updated
:更新包含綁定值的元素后調用。 -
beforeUnmount
:在綁定元素從 DOM 中移除前調用。 -
unmounted
:綁定元素從 DOM 中移除后調用。
通過這些生命周期,可以實現復雜的邏輯,例如初始化資源、監聽事件或清理操作。
2. 基礎部分:v-copy
指令
目標:實現一個簡單的復制文本功能。
實現代碼
將復制文本的邏輯單獨抽離為工具函數:
// src/utils/copyToClipboard.js
export function copyToClipboard(text) {const input = document.createElement('textarea');input.value = text;document.body.appendChild(input);input.select();try {document.execCommand('copy');document.body.removeChild(input);return true;} catch (err) {document.body.removeChild(input);throw new Error('復制失敗');}
}
封裝 v-copy
指令:
// src/directives/copy.js
import { copyToClipboard } from '../utils/copyToClipboard';
import { isFunction } from '../utils/isType';
export default {mounted(el, binding) {const handleClick = () => {try {copyToClipboard(binding.value);console.log('復制成功!');} catch (err) {console.error('復制失敗:', err);}};el.__handleClick__= handleClick;el.removeEventListener('click', el.__handleClick__);el.addEventListener('click', handleClick);},unmounted(el) {el.removeEventListener('click', el.__handleClick__);delete el.__handleClick__;},
};
使用方式
在 Vue 項目中全局注冊指令:
// main.js
import { createApp } from 'vue';
import App from './App.vue';
import copyDirective from './directives/copy';
const app = createApp(App);
app.directive('copy', copyDirective);
app.mount('#app');
在組件中使用:
<template><button v-copy="'這是復制的文本'">點擊復制</button>
</template>
3. 進階部分:完善的 v-copy
指令
目標:增強功能,支持成功和失敗的事件回調。
實現代碼
// src/directives/copy.js
import { copyToClipboard } from '../utils/copyToClipboard';
import { isFunction } from '../utils/isType';
export default {mounted(el, binding) {const handleClick = () => {const { success, error } = binding.arg || {};try {copyToClipboard(binding.value);if (isFunction(success)) {success();}} catch (err) {if (isFunction(error)) {error(err);}}};el.__handleClick__ = handleClick;el.removeEventListener('click', el.__handleClick__);el.addEventListener('click', handleClick);},unmounted(el) {el.removeEventListener('click', el.__handleClick__);delete el.__handleClick__;},
};
使用方式
<template><buttonv-copy:success="onCopySuccess"v-copy:error="onCopyError"v-copy="'高級復制文本'">高級復制按鈕</button>
</template>
<script>
export default {methods: {onCopySuccess() {alert('復制成功!');},onCopyError(err) {alert('復制失敗:' + err.message);},},
};
</script>
4. 指令參數說明
-
binding.value
:指令綁定的值,在這里是需要復制的文本。 -
binding.arg
:可選參數,例如用于傳遞回調函數(如success
和error
)。 -
binding.modifiers
:修飾符對象,可用于定義指令的額外行為(如條件觸發等)
5. 多指令項目的目錄結構
當項目中包含多個自定義指令時,建議按照以下方式組織:
src/
├── directives/
│ ├── index.js # 統一導出所有指令
│ ├── copy.js # 復制指令
│ ├── focus.js # 聚焦指令
│ └── lazy-load.js # 圖片懶加載指令
├── utils/
│ ├── copyToClipboard.js # 工具函數
│ └── isType.js # 類型判斷工具
統一導出指令
// src/directives/index.js
import copy from './copy';
import focus from './focus';
import lazyLoad from './lazy-load';
export default {copy,focus,lazyLoad,
};
全局注冊指令
// main.js
import { createApp } from 'vue';
import App from './App.vue';
import directives from './directives';
const app = createApp(App);
Object.keys(directives).forEach((key) => {app.directive(key, directives[key]);
});
app.mount('#app');
通過這樣的目錄結構,指令的維護和擴展將更加方便有序。如果需要新增指令,只需在 directives
目錄中添加對應的文件并更新 index.js
即可。
希望本文能夠幫助您更好地掌握 Vue 3 的自定義指令開發!
6.團隊介紹
「三翼鳥數字化技術平臺-定制平臺開發」主要負責設計工具的研發,包括營銷設計工具、家電VR設計和展示、水電暖通前置設計能力,研發并沉淀素材庫,構建家居家裝素材庫,集成戶型庫、全品類產品庫、設計方案庫、生產工藝模型,打造基于戶型和風格的AI設計能力,快速生成算量和報價;同時研發了門店設計師中心和項目中心,包括設計師管理能力和項目經理管理能力。實現了場景全生命周期管理,同時為水,空氣,廚房等產業提供商機管理工具,從而實現了以場景貫穿的B端C端全流程系統。