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 组件中使用它们。这样的结构使自定义指令的管理更加集中和清晰。