Vue3 自定义指令Custom Directives

简介

        在vue中重用代码的方式有:组件、组合式函数。组件是主要的构建模块,而组合式函数更偏重于有状态的逻辑。

        指令系统给我们提供了例如:v-model、v-bind,vue系统允许我们自定义指令,自定义指令也是一种重用代码的方式。自定义指令常用于封装一些普通元素的Dom底层访问逻辑。

定义

        一个自定义指令由一个包含类似组件生命周期钩子的对象来定义。钩子函数会接收到指令所绑定元素作为其参数。

        自定义指令的钩子函数如下:

const myDirective = {// 在绑定元素的 attribute 前// 或事件监听器应用前调用created(el, binding, vnode, prevVnode) {// 下面会介绍各个参数的细节},// 在元素被插入到 DOM 前调用beforeMount(el, binding, vnode, prevVnode) {},// 在绑定元素的父组件// 及他自己的所有子节点都挂载完成后调用mounted(el, binding, vnode, prevVnode) {},// 绑定元素的父组件更新前调用beforeUpdate(el, binding, vnode, prevVnode) {},// 在绑定元素的父组件// 及他自己的所有子节点都更新后调用updated(el, binding, vnode, prevVnode) {},// 绑定元素的父组件卸载前调用beforeUnmount(el, binding, vnode, prevVnode) {},// 绑定元素的父组件卸载后调用unmounted(el, binding, vnode, prevVnode) {}
}

 使用     

        下面这两个使用的例子都源自网络,在原有的基础上加入了一些改动  

        一个小栗子,使用全局自定义指令封装防抖代码段

export function preventReClick(app) {app.directive('preventReClick', {beforeMount(el, binding) {el.addEventListener('click', () => {if (!el.disabled) {el.disabled = truesetTimeout(() => {el.disabled = false}, binding.value || 3000)}})}})
}
import App from './App.vue'
import { preventReClick } from './utils/directivebox';const app = createApp(App)// 全局指令的挂载
preventReClick(app);
<template><div class="box"><!-- 这里必须使用el-button,因为这个防抖的功能是通过控制elementPlus中的disable属性实现的 --><el-button class="btn" v-preventReClick @click="buttonEvent">使用全局自定义指令,做防抖的处理</el-button></div>
</template>
<script setup>let clickNum = 0// 使用全局自定义指令处理防抖
/*运行后可以看到,在连续多次点击button时,3000ms后才会打印一次这个buttonEvent中的log因为在全局自定义指令中拦截了click的事件,在3000ms内组件被设置为disabled的状态*/
function buttonEvent() {clickNum++console.log("clickNum = ", clickNum); 
}</script>
<style scoped lang="less">
.box {display: flex;flex-direction: column;.btn {padding: 20px 40px 20px 40px;background-color: aquamarine;margin-bottom: 30px;}
}
</style>

 一个小栗子,使用局部自定义指令封装长按元素两秒的点击事件:

export const longpress = {created(el, binding, vNode) {// console.log("long press event 1");if (typeof binding.value !== 'function') {throw 'callback must be a function'}// 定义变量let pressTimer = null// 创建计时器( 2秒后执行函数 )let start = (e) => {if (e.type === 'click' && e.button !== 0) {return}if (pressTimer === null) {pressTimer = setTimeout(() => {handler()}, 2000)}}// 取消计时器let cancel = (e) => {if (pressTimer !== null) {clearTimeout(pressTimer)pressTimer = null}}// 运行函数const handler = (e) => {binding.value(e)}// 添加事件监听器el.addEventListener('mousedown', start)el.addEventListener('touchstart', start)// 取消计时器el.addEventListener('click', cancel)el.addEventListener('mouseout', cancel)el.addEventListener('touchend', cancel)el.addEventListener('touchcancel', cancel)},// 当传进来的值更新的时候触发updated(el, { value }) {el.$value = value},// 指令与元素解绑的时候,移除事件绑定unmounted(el) {el.removeEventListener('click', el.handler)},
}
<template><div class="box"><el-button class="btn" v-long-press="longPressEvent">使用全局自定义指令,实现长按处理事件</el-button></div>
</template>
<script setup>
import { longpress } from './utils/derective.js'// 在setup语法糖中使用v打头驼峰命名的方式声明一个局部的自定义指令
const vLongPress = longpress;function longPressEvent(){console.log("button的长按点击事件");
}</script>
<style scoped lang="less">
.box {display: flex;flex-direction: column;.btn {padding: 20px 40px 20px 40px;background-color: aquamarine;margin-bottom: 30px;}
}
</style>

小结

        注意:只有当所需功能只能通过直接的 DOM 操作来实现时,才应该使用自定义指令。其他情况下应该尽可能地使用 v-bind 这样的内置指令来声明式地使用模板,这样更高效,也对服务端渲染更友好。

    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/797270.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring boot微服务分布式框架Rouyi Cloud权限认证

&#x1f339;作者主页&#xff1a;青花锁 &#x1f339;简介&#xff1a;Java领域优质创作者&#x1f3c6;、Java微服务架构公号作者&#x1f604; &#x1f339;简历模板、学习资料、面试题库、技术互助 &#x1f339;文末获取联系方式 &#x1f4dd; 往期热门专栏回顾 专栏…

Go 程序的启动流程【1/2】

Go 程序的启动流程 本文将以一个简单的 HelloWorld 程序为例&#xff0c;探究 Go 程序的启动流程 package mainfunc main() {_ "Hello World" }入口 我们先通过 go build . 将代码编译成可执行文件&#xff0c;众所周知&#xff0c;我们在一个 shell 中执行可执行…

memset()函数及其作用

一、memset() memset()函数是C/C语言中的一个标准库函数&#xff0c;用于将一块内存空间的内容设置为指定的值。 其函数原型为&#xff1a; void *memset(void *ptr, int value, size_t num); 参数说明&#xff1a; - ptr: 指向要设置数值的内存块的指针。 - value: 要设置…

CLoVe:在对比视觉语言模型中编码组合语言

CLoVe:在对比视觉语言模型中编码组合语言 摘要引言相关工作CLoVe: A Framework to Increase Compositionality in Contrastive VLMsSynthetic CaptionsHard NegativesModel Patching CLoVe: Encoding Compositional Language inContrastive Vision-Language Models 摘要 近年来…

【C++风云录】优秀的C++日志库:让日志记录与调试变得轻松

日志记录与调试 日志记录与调试&#xff1a;提升C项目开发效率的利器 前言 在C项目开发过程中&#xff0c;日志记录与调试是非常重要的环节。通过对程序的运行过程进行日志记录&#xff0c;开发者可以快速定位问题和追踪代码的执行情况&#xff0c;提高开发效率和代码质量。…

记一次安服薅洞实战

记一次为数不多但还算有点收获的一次实战&#xff08;平时摸鱼来着...&#xff09;&#xff0c;大致任务是对某某市某*院进行次漏洞收集和外网资产梳理且是有授权的&#xff08;其实是甲方不大清楚自己外网有多少资产&#xff09;&#xff0c;漏洞质量要求还挺高。emmm本来是打…

大米自动化生产线设备:现代粮食加工的核心力量

随着科技的不断进步和粮食加工行业的快速发展&#xff0c;大米自动化生产线设备在现代粮食加工中的地位愈发重要。这些设备不仅大大提高了生产效率&#xff0c;还保证了产品的质量和安全&#xff0c;成为了现代粮食加工行业不可或缺的核心力量。 一、自动化生产线设备助力效率提…

【面试经典150 | 动态规划】交错字符串

文章目录 写在前面Tag题目来源解题思路方法一&#xff1a;动态规划 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对于本题涉及到的数据结构等内容进行…

一些Java面试题

1、 Java语言有哪些特点 1、简单易学、有丰富的类库 2、面向对象&#xff08;Java最重要的特性&#xff0c;让程序耦合度更低&#xff0c;内聚性更高&#xff09; 3、与平台无关性&#xff08;JVM是Java跨平台使用的根本&#xff09; 4、可靠安全 5、支持多线程 2、面向对象和…

1.8.3 卷积神经网络近年来在结构设计上的主要发展和变迁——GoogleNet/inception-v1

1.8.3 卷积神经网络近年来在结构设计上的主要发展和变迁——GoogleNet/ inception-v1 前情回顾&#xff1a; 1.8.1 卷积神经网络近年来在结构设计上的主要发展和变迁——AlexNet 1.8.2 卷积神经网络近年来在结构设计上的主要发展和变迁——VGGNet GoogleNet问题 在VGGNet简单堆…

(2024)Ubuntu源码安装多个版本的opencv并切换使用

本人工作会用到x86_64的opencv和aarch64的opencv&#xff0c;所以写下来备忘自用 一、源码编译安装 依赖库安装&#xff1a; sudo apt-get install build-essential libgtk2.0-dev libgtk-3-dev libavcodec-dev libavformat-dev libjpeg-dev libswscale-dev libtiff5-dev o…

卷积神经网络实战

构建卷积神经网络 卷积网络中的输入和层与传统神经网络有些区别&#xff0c;需重新设计&#xff0c;训练模块基本一致 1.首先读取数据 - 分别构建训练集和测试集&#xff08;验证集&#xff09; - DataLoader来迭代取数据 # 定义超参数 input_size 28 #图像的总尺寸28*28…

JSX 和 HTML 之间的区别

JSX和 HTML 都是用于创建和构建网页的标记语言&#xff0c;但它们有一些关键的区别。 1. JSX 是 JavaScript 的语法扩展&#xff0c;而 HTML 是一种标记语言。 2. JSX 允许您在语法中包含表达式和函数&#xff0c;而 HTML 只允许静态文本。 3. JSX 通常用于 React 应用程序&…

Spring Boot整合Kafka+SSE实现实时数据展示

2024年3月10日 知识积累 为什么使用Kafka&#xff1f; 不使用Rabbitmq或者Rocketmq是因为Kafka是Hadoop集群下的组成部分&#xff0c;对于大数据的相关开发适应性好&#xff0c;且当前业务场景下不需要使用死信队列&#xff0c;不过要注意Kafka对于更新时间慢的数据拉取也较…

73.矩阵置零

题目描述 解题思路 ——————初步思路&#xff0c;暴力求解—————— 1.遍历原矩阵&#xff0c;记录0位置的行列值&#xff0c;存入数组flags中&#xff0c;作为标志 2.读取flags中的元素&#xff0c;获取要置为0的行列值&#xff0c;然后两个循环将matrix中的对应元…

【代码】二分法求最小值

仅适用于以下情况&#xff1a;区间内单调或者最多一个极小值 代码 以[0,pi]内的三角函数为例 clc clear close allx0:pi/1000:pi; ytest(x); figure() plot(x,y,.)cutnum100;x1x(1); x2x(end); error_max10^-1000;%能接受的误差上限 for i1:cutnum%这里cutnum是取值上限num(…

电池二次利用走向可持续大循环周期的潜力和挑战(第一篇)

一、背景 当前&#xff0c;气候变化是全球可持续发展面临的重大挑战。缓解气候变化最具挑战性的目标是在本世纪中期实现碳中和&#xff08;排放量低到足以被自然系统安全吸收&#xff09;&#xff0c;其中电动汽车&#xff08;EV&#xff09;的引入是一项关键举措。电动汽车在…

SSL根证书是什么

根证书是什么&#xff1f; 根证书是CA认证中心给自己颁发的证书,是信任链的起始点。安装根证书意味着对这个CA认证中心的信任。 从技术上讲&#xff0c;证书其实包含三部分&#xff0c;用户的信息&#xff0c;用户的公钥&#xff0c;还有CA中心对该证书里面的信息的签名&#…

对代理模式的理解

目录 一、前言二、案例1 代码2 自定义代理类【静态代理】2.1 一个接口多个实现&#xff0c;到底注入哪个依赖呢&#xff1f;2.1.1 Primary注解2.1.2 Resource注解&#xff08;指定name属性&#xff09;2.1.3 Qualifier注解 2.2 面向接口编程2.3 如果没接口咋办呢&#xff1f;2.…

替代安全指标(Surrogate Safety Measures (SSM) )

替代安全措施&#xff08;Surrogate Safety Measures (SSM) &#xff09;用于从数据中寻找接近碰撞&#xff0c;或可能发生&#xff08;但实际没有发生&#xff09;的碰撞事件。 SSM的两个合格标准&#xff1a; &#xff08;1&#xff09;它应该来自与碰撞直接相关的交通冲突&…