ts实现全局注册自定义指令和自定义插件对象

一、全局注册自定义指令 ,以 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');
3、然后就可以在全局使用对应的组件了,不需要在组件中import了。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值