Vue3+ts自定义指令
1. 在 directives/index.ts 中整合自定义指令:
在 src/directives/index.ts 文件中定义多个自定义指令。
// 防抖指令
interface DebounceBinding {(): void;time?: number;logPrefix?: string;
}export const debounce: Directive = {mounted(el: HTMLElement, binding: { arg: string; value: DebounceBinding }) {let timer: NodeJS.Timeout | null = null;el.addEventListener(binding.arg, () => {if (timer) {clearTimeout(timer);}const delay = binding.value.time || 300;const logPrefix = binding.value.logPrefix || 'Debounce';timer = setTimeout(() => {console.log(`${logPrefix}: 防抖后的函数执行`);binding.value();}, delay);});},unmounted(el: HTMLElement) {if (timer) {clearTimeout(timer);}}
};// 聚焦指令
export const focus: Directive = {inserted(el: HTMLElement) {el.focus();}
};// 图片懒加载指令
export const lazyload: Directive = {mounted(el: HTMLImageElement, binding: { value: string }) {const img = new Image();const loadingClass = 'image-loading';const errorClass = 'image-error';el.classList.add(loadingClass);const observer = new IntersectionObserver((entries, observer) => {entries.forEach(entry => {if (entry.isIntersecting) {img.src = binding.value;img.onload = () => {el.src = binding.value;el.classList.remove(loadingClass);observer.unobserve(el);};img.onerror = () => {el.classList.remove(loadingClass);el.classList.add(errorClass);observer.unobserve(el);};}});});observer.observe(el);}
};
2. 在 main.ts 中全局注册自定义指令:
import { createApp } from 'vue';
import App from './App.vue';
import { debounce, focus, lazyload } from './directives';const app = createApp(App);app.directive('debounce', debounce);
app.directive('focus', focus);
app.directive('lazyload', lazyload);app.mount('#app');
3. 在组件中使用自定义指令:
在 XXX.vue 中使用这几个自定义指令。
<template><div><input v-focus type="text" placeholder="自动聚焦"><input type="text" v-debounce:input="inputDebounce" :time="500" :logPrefix="自定义前缀">< img v-lazyload="imageUrl" alt="示例图片"></div>
</template><script setup lang="ts">
const inputDebounce = () => {console.log('实际执行的函数');
};const imageUrl = 'your-image-url.jpg';
</script>
在上述代码中,我们将 debounce 和 focus 两个自定义指令都定义在 directives/index.ts 文件中,然后在 main.ts 中进行全局注册,并在 App.vue 组件中使用它们。这样的结构使自定义指令的管理更加集中和清晰。