一、全局注册自定义指令 ,以 debounce 防抖函数为例
1、文件目录
2、 debounce.ts 文件用来写 debounce 的实现逻辑
/**
* v-debounce
* 防抖指令,可自行扩展到input
* 接受参数:function类型
*/
import type { Directive, DirectiveBinding } from 'vue'
interface ElType extends HTMLElement {
__handleInput__:(event:Event) => any
}
const debounce: Directive = {
mounted(el: ElType, binding: DirectiveBinding) {
console.log(el, 'el');
console.log(binding, 'binding');
if (typeof binding.value.callback !== 'function') {
throw new Error('callback must be a function')
}
let timer:any= null
el.__handleInput__ = (event: Event) => {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
binding.value.callback(event)
},parseInt(binding.value.delay || '500')) // 默认是500ms
}
// 监听el元素的input事件
el.addEventListener('input', el.__handleInput__)
},
beforeUnmount(el: ElType) {
el.removeEventListener('input',el.__handleInput__)
},
}
export default debounce
3、在 index.ts 文件中实现注册逻辑
import { App,Directive } from "vue";
import debounce from "./modules/debounce";
interface GlobalDirective {
[key:string]: Directive
}
const directivesObj: GlobalDirective= {
debounce
}
const directives = {
install(app:App) {
Object.keys(directivesObj).forEach(key => {
console.log(app);
app.directive(key,directivesObj[key])
})
}
}
export default directives
4、在 main.ts 中全局注册使用
import { createApp } from 'vue';
import App from './App.vue';
import directives from '@/directives';
const app = createApp(App);
app.use(directives);
app.mount('#app');
5、使用
顺便提一下防抖的作用
防抖可以控制事件被触发的频率,在用户输入的时候,可以延迟触发验证或搜索操作,以避免频繁的输入带来的性能问题,提升用户体验。
<!-- 演示代码 -->
<template>
<h4>使用 v-debounce 指令</h4>
<input
type="text"
v-model="inputVal"
v-debounce="{
delay: 1000,
event: 'input',
callback: debounceInput,
}"
/>
<h4>不使用防抖</h4>
<input type="text" v-model="inputVal1" @input="onInput" />
</template>
<script setup lang="ts">
import { ref } from 'vue';
defineOptions({
name: '404',
});
const inputVal = ref('');
const inputVal1 = ref('');
const debounceInput = () => {
console.log(inputVal.value, '使用了防抖');
};
const onInput = () => {
console.log(inputVal1, '没有使用防抖');
};
</script>
<style scoped></style>
简单演示一下
没有使用防抖指令的时候,用户的输入会频繁的触发对应的input事件
二、全局注册自定义插件对象,跟自定义指令的思想是一样的
1、以 ElementPlusIconsVue 组件为例
// 引入项目中需要全局注册的组件
import xxx from './xxx.vue';
// 导入 Vue 相关的类型
import { App, Component } from 'vue';
import * as ElementPlusIconsVue from '@element-plus/icons-vue';
// 定义 allGlobalComponent 的类型
interface GlobalComponents {
[key: string]: Component;
}
const allGlobalComponent: GlobalComponents = {
xxx,
...ElementPlusIconsVue,
};
// 对外暴露插件对象
export default {
install(app: App) {
Object.keys(allGlobalComponent).forEach((key) => {
app.component(key, allGlobalComponent[key]);
});
},
};
2、在 mian.ts 中引入
import { createApp } from 'vue';
import App from './App.vue';
// 引入自定义插件对象:注册整个项目全局组件
import gloablComponent from '@/components';
const app = createApp(App);
app.use(gloablComponent);
app.mount('#app');