2. vue-sy-admin: 基于vue3+TypeScript的自定义指令(directives)的封装及示例

2023-10-14 08:44

本文主要是介绍2. vue-sy-admin: 基于vue3+TypeScript的自定义指令(directives)的封装及示例,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

自定义指令directives在项目特别是后台管理类的项目中使用的尤其多(个人经验),每个人编写的自定义指令也各不相同,一个人的时候还没啥感觉,在多人合作的项目中统一编码规范就变得很有必要了,这样看着舒服的同时也更方便后期维护。

题外话: 强烈推荐使用 vueuse,该库由vue核心成员开发,封装了各种常用hooks,能够省很多不必要的开发时间,且其中的封装hooks思想也很值得学习参考

最终效果如下图所示

Snipaste_2023-10-13_12-20-15.png

1. directives自定义指令创建及类型参数声明

src/directives目录下新建 index.tstypes.ts 分别用于自定义指令directives的注册及全局指令参数声明。另新建目录modules用于存放各种不同的指令实现代码。

// index.ts
import type { App } from 'vue';
import type { DirectiveOptions, Keys } from './types';export default async function directives(app: App) {// 项目是用 vite 创建,import.meta.glob 用于导入 /modules 下所有指令实现代码const files = import.meta.glob('./modules/*.ts');for (const key in files) {const file: any = await files[key]();if (file) {const direct = file.default as DirectiveOptions<Keys>;app.directive(direct.name, direct.directive);}}
}
// types.ts
import type { Directive } from 'vue';
type EventTypes = 'click' | 'input';export interface ELType extends HTMLElement {__fn__: () => any;
}export interface Directives {vFocus: Directive; // 聚焦vDebounce: Directive<any,{type?: EventTypes;delay?: number;callback: (...args: any[]) => void;}>; // 防抖
}export type Keys = keyof Directives;// 指令名转小写
type LowerDirectiveName<T extends Keys> = T extends `v${infer V}`? Lowercase<V>: never;// 指令对象类型
export interface DirectiveOptions<T extends Keys> {name: LowerDirectiveName<T>;directive: Directives[T];
}

注:types.ts导出接口声明Directives主要用于在vue组件的ComponentCustomProperties中作声明使用。

聚焦指令(v-focus)实现
import type { DirectiveOptions } from '../types';const focusDirective: DirectiveOptions<'vFocus'> = {name: 'focus',directive: {mounted: (el: HTMLInputElement) => el.focus(),},
};export default focusDirective;
防抖指令(v-debounce)代码实现
// modules/debounce.tsimport { useDebounceFn } from '@vueuse/core'
import type { DirectiveOptions, ELType } from '../types';const focusDirective: DirectiveOptions<'vDebounce'> = {name: 'debounce',directive: {mounted: (el: ELType, { value }, vnode) => {const { type = 'input', delay, callback } = value;el.__fn__ = useDebounceFn(callback.bind(vnode), delay ?? 300);el.addEventListener(type, el.__fn__);},beforeUnmount: (el: ELType, { value }) => {el.removeEventListener(value.type || 'input', el.__fn__);},},
};export default focusDirective;

2. 注册自定义指令directives

在入口文件 main.ts中引入并注册即可

// main.ts
import { createApp } from 'vue';
import directives from './directives';const app = createApp(App);
app.use(directives);
app.mount('#app');

3. 为.vue文件添加自定义指令类型声明

// global-properties.d
import type { Component } from 'vue';
import type { Filter } from '../src/filters/types';
import type { Directives } from '@/directives/types';declare module 'vue' {// 在这里直接继承 Directives 即可interface ComponentCustomProperties  extendsComponent, Directives {$filters: Filter;}
}

注:别忘了将该文件加入tsconfig.json的include配置项中,否则在.vue文件的template中使用将不会出现类型提示。

在线代码可查看:vue-sy-admin
简易模板可查看:vue-vite-template

这篇关于2. vue-sy-admin: 基于vue3+TypeScript的自定义指令(directives)的封装及示例的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/209405

相关文章

SpringBoot线程池配置使用示例详解

《SpringBoot线程池配置使用示例详解》SpringBoot集成@Async注解,支持线程池参数配置(核心数、队列容量、拒绝策略等)及生命周期管理,结合监控与任务装饰器,提升异步处理效率与系统... 目录一、核心特性二、添加依赖三、参数详解四、配置线程池五、应用实践代码说明拒绝策略(Rejected

SQL中如何添加数据(常见方法及示例)

《SQL中如何添加数据(常见方法及示例)》SQL全称为StructuredQueryLanguage,是一种用于管理关系数据库的标准编程语言,下面给大家介绍SQL中如何添加数据,感兴趣的朋友一起看看吧... 目录在mysql中,有多种方法可以添加数据。以下是一些常见的方法及其示例。1. 使用INSERT I

SpringBoot中SM2公钥加密、私钥解密的实现示例详解

《SpringBoot中SM2公钥加密、私钥解密的实现示例详解》本文介绍了如何在SpringBoot项目中实现SM2公钥加密和私钥解密的功能,通过使用Hutool库和BouncyCastle依赖,简化... 目录一、前言1、加密信息(示例)2、加密结果(示例)二、实现代码1、yml文件配置2、创建SM2工具

MySQL 定时新增分区的实现示例

《MySQL定时新增分区的实现示例》本文主要介绍了通过存储过程和定时任务实现MySQL分区的自动创建,解决大数据量下手动维护的繁琐问题,具有一定的参考价值,感兴趣的可以了解一下... mysql创建好分区之后,有时候会需要自动创建分区。比如,一些表数据量非常大,有些数据是热点数据,按照日期分区MululbU

Python函数作用域示例详解

《Python函数作用域示例详解》本文介绍了Python中的LEGB作用域规则,详细解析了变量查找的四个层级,通过具体代码示例,展示了各层级的变量访问规则和特性,对python函数作用域相关知识感兴趣... 目录一、LEGB 规则二、作用域实例2.1 局部作用域(Local)2.2 闭包作用域(Enclos

C++20管道运算符的实现示例

《C++20管道运算符的实现示例》本文简要介绍C++20管道运算符的使用与实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录标准库的管道运算符使用自己实现类似的管道运算符我们不打算介绍太多,因为它实际属于c++20最为重要的

Java中调用数据库存储过程的示例代码

《Java中调用数据库存储过程的示例代码》本文介绍Java通过JDBC调用数据库存储过程的方法,涵盖参数类型、执行步骤及数据库差异,需注意异常处理与资源管理,以优化性能并实现复杂业务逻辑,感兴趣的朋友... 目录一、存储过程概述二、Java调用存储过程的基本javascript步骤三、Java调用存储过程示

ModelMapper基本使用和常见场景示例详解

《ModelMapper基本使用和常见场景示例详解》ModelMapper是Java对象映射库,支持自动映射、自定义规则、集合转换及高级配置(如匹配策略、转换器),可集成SpringBoot,减少样板... 目录1. 添加依赖2. 基本用法示例:简单对象映射3. 自定义映射规则4. 集合映射5. 高级配置匹

Golang如何对cron进行二次封装实现指定时间执行定时任务

《Golang如何对cron进行二次封装实现指定时间执行定时任务》:本文主要介绍Golang如何对cron进行二次封装实现指定时间执行定时任务问题,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录背景cron库下载代码示例【1】结构体定义【2】定时任务开启【3】使用示例【4】控制台输出总结背景

C++11作用域枚举(Scoped Enums)的实现示例

《C++11作用域枚举(ScopedEnums)的实现示例》枚举类型是一种非常实用的工具,C++11标准引入了作用域枚举,也称为强类型枚举,本文主要介绍了C++11作用域枚举(ScopedEnums... 目录一、引言二、传统枚举类型的局限性2.1 命名空间污染2.2 整型提升问题2.3 类型转换问题三、C