当前位置: 首页 > news >正文

Directives Vue3 自定义指令

目录

- 什么是自定义指令:

- 怎么识别自定义指令:

- 自定义指令分析


- 什么是自定义指令:

在 Vue.js 中,自定义指令的常用生命周期钩子函数通常是mounted、updated、unmounted

这些钩子函数接收参数 el 和 binding。

- 怎么识别自定义指令:


看到 el 和 binding 作为函数参数出现,特别是在 mounted 和 unmounted 钩子中,这是一个明确的标志,表明这是一个 Vue.js 的自定义指令。

- 自定义指令分析

const obj = {name: "change",createHandler: (el, binding, fn) => {return function (...args) {fn.apply(null, args);};},alias: {hover: "mouseenter",},pairs: {mouseenter: "mouseleave",mouseover: "mouseout",},mounted(el, binding) {binding.arg = binding.arg || "mouseenter"; // 提供默认事件binding.arg = obj.alias[binding.arg] || binding.arg; // 检查别名binding.flag = true; // 初始状态binding.originalStyles = {}; // 存储原始样式const cs = window.getComputedStyle(el);for (let key in binding.value) {binding.originalStyles[key] = cs[key]; // 获取并存储原始样式}binding.eventHandler = obj.createHandler(el, binding, (e) => {let styles = binding.value;if (binding.modifiers.clear) {styles = binding.flag ? binding.value : binding.originalStyles; // 根据 flag 决定应用哪种样式}for (let key in styles) {el.style[key] = styles[key]; // 应用样式}binding.flag = !binding.flag; // 切换 flag 状态});el.addEventListener(binding.arg, binding.eventHandler); // 绑定事件处理函数if (obj.pairs[binding.arg]) {binding.clearHandler = obj.createHandler(el, binding, (e) => {for (let key in binding.originalStyles) {el.style[key] = binding.originalStyles[key]; // 清除样式}});el.addEventListener(obj.pairs[binding.arg], binding.clearHandler); // 绑定配对事件处理函数}},unmounted(el, binding) {el.removeEventListener(binding.arg, binding.eventHandler); // 移除事件处理函数binding.eventHandler = null;if (binding.clearHandler) {el.removeEventListener(obj.pairs[binding.arg], binding.clearHandler); // 移除配对事件处理函数binding.clearHandler = null;}},
};export default obj;

1. createHandler部分疑问:

createhandler是对象中的一个方法  用于创建事件处理函数,createhandler返回一个新函数  新函数接受任意数量的参数 

问:作用是回调函数里返回一个新函数 该新函数将收到的args作用到原回调函数fn上?

作用是创建一个新的事件处理函数。这个新函数接收任意数量的参数(通过 ...args),并将这些参数传递给原始回调函数 fn。
当事件触发时,事件对象(event)会作为参数传递给这个新函数,它会调用 fn 并将参数应用到 fn 上

2. 成对的事件,在pair部分:为啥成对的事件才要绑定事件清除?
    成对事件是为了确保在某些情况下能够恢复样式。例如,mouseenter 和 mouseleave 是成对的事件,当鼠标进入时应用样式,当鼠标离开时恢复样式。

这段代码检查是否存在配对事件(例如 mouseenter 的配对事件是 mouseleave)。
如果存在配对事件,创建 clearHandler,用于在配对事件触发时恢复原始样式,并将 clearHandler 绑定到配对事件上。

所以这里的pair的作用是什么?

pairs 对象定义成对的事件,比如mouseenter对应mouseleave
mouseover对应 mouseout
当某个事件被绑定时 比如mouseenter 为了
**确保 事件触发后样式能恢复原样** 会绑定一个配对的事件 mouseleave来清除应用 的样式

3. binding.arg = binding.arg || "mouseenter"
    //第一遍 看 v-change后有无参数
    binding.arg = obj.alias[binding.arg] || binding.arg
    //第二遍 别名例如hover优先

4. binding.flag=true
    //如果有flag则要是有修饰符如clear则立即调整样式?为何要切换flag状态 ?


    切换 flag 状态是为了在每次事件触发时交替应用和恢复样式。
如果 flag 是 true,则应用 binding.value 中的样式;如果 flag 是 false,则恢复原始样式。这种切换确保了在事件反复触发时能够在两种样式状态之间切换。

如果有flag那么就更新当前binding.value状态不然就用originalStyles?
flag用于切换样式状态的标志  如果flag为true 应用binding.value里样式,否则恢复到originalstyles
半修饰符 clear存在时根据flag的值决定应用哪种样式

5 el.addEventListener(obj.pairs[binding.arg],binding.clearHandler)
    //这是定义完毕回调事件直接应用到元素el上?
    这行代码将 binding.eventHandler 绑定到指定的事件上(例如 mouseenter)。
当事件发生时,eventHandler 会被触发,执行样式更新逻辑。

- binding.arg的处理

mounted钩子里  binding.arg 就是指令绑定的参数 模板中使用指令
<div v-change:mouseenter></div>
这里mouseenter就是binding.arg

binding.arg = binding.arg ||"mouseenter"表示如果 binding.arg 没有定义默认为mouseenter

第一个是确保binding.arg有默认值
第二个赋值是处理可能的别名映射

mounted里两次赋值给binding.arg  应该是以别名为主?别名就覆盖了原本 的binding.arg?

第一次赋值是提供默认值 确保 binding.arg有值
第二次赋值 是为了检查是否有别名  如果存在别名 则将binding.arg 
换为别名对应的值

确实别名优先级高于原本的 binding.arg

binding.value是指令的绑定值

<div v-change:mouseenter="{color:'red'}">
这里 {color:'red'}就是binding.value
binding:value 不包含flag和arg

window.getComputedStyle什么用

   window.getComputedStyle(el)返回一个对象 该对象包含el所有css样式的当前值
   使用他可以获取元素当前应用的所有样式

binding.value 与 binding.originalStyles

bingding.originalStyles 存储的是元素在应用 binding.value之前的原始样式

binding.value是指令绑定的值
可以包含多个css属性和值  
{color:"red", backgroundColor:'blue'}
 

binding.originalStyles[key]=cs[key]
这个赋值语句在干嘛:这是把每一个 binding.value中的键对应的当前样式存储起来

这里的binding.modifiers.clear什么含义?

这是指令的修饰符 <div v-vhange:mouseenter.clear="{color:'red'}">
clear就是个修饰符  binding.modifiers.clear被解析为true或者false

存储的是元素在应用指令样式前的原始样式
事件触发后能恢复元素的原始样式

binding.arg = obj.alias["hover"] || "hover";
obj.alias["hover"] 是 "mouseenter",所以 binding.arg 最终变成 "mouseenter"。
obj.alias["mouseenter"] 是 undefined,所以 binding.arg 依然是 "mouseenter"。

所以这整个代码是  定义了一个自定义指令 v-change,它可以监听指定的事件(通过 binding.arg 或其别名),并在事件触发时应用或恢复样式。
在元素挂载时,初始化 binding.arg,存储原始样式,并创建和绑定事件处理函数。
在事件触发时,根据 flag 切换样式或恢复原始样式。
在元素卸载时,移除所有绑定的事件处理函数。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 由于安全风险,安全领导者考虑禁止人工智能编码
  • 【html】基础(一)
  • SQLServer数据分页
  • 关于 mybatis-plus-boot-starter 与 mybatis-spring-boot-starter 的错误
  • 快速理解TCP协议(一)——TCP协议深度解析
  • Ubuntu20.04 搜索不到任何蓝牙设备
  • 微软宣布弃用面向企业的WSUS更新服务 仍然保留该服务但不再添加任何新功能
  • 50页PPT麦肯锡精益运营转型五步法
  • Android RecyclerView 实现 GridView ,并实现点击效果及方向位置的显示
  • 只装了WPS,DOC文档无法打开
  • 第二章 SpringBoot环境下yml和properties的几种玩法
  • 美信监控易的优势:长期稳定运行
  • 让AI激发创作力:OpenAI分享5位专业作家利用ChatGPT写作的案例技巧
  • JSP 指令标识和脚本标识的使用
  • 828 华为云征文|华为 Flexus 云服务器搭建 SamWaf 开源轻量级网站防火墙
  • 【个人向】《HTTP图解》阅后小结
  • AHK 中 = 和 == 等比较运算符的用法
  • angular组件开发
  • JAVA SE 6 GC调优笔记
  • Laravel5.4 Queues队列学习
  • PhantomJS 安装
  • React+TypeScript入门
  • SQLServer之创建数据库快照
  • tweak 支持第三方库
  • vuex 笔记整理
  • 案例分享〡三拾众筹持续交付开发流程支撑创新业务
  • 读懂package.json -- 依赖管理
  • 全栈开发——Linux
  • 微信小程序设置上一页数据
  • 云栖大讲堂Java基础入门(三)- 阿里巴巴Java开发手册介绍
  • ​​​​​​​​​​​​​​汽车网络信息安全分析方法论
  • ###C语言程序设计-----C语言学习(6)#
  • #绘制圆心_R语言——绘制一个诚意满满的圆 祝你2021圆圆满满
  • (2024)docker-compose实战 (9)部署多项目环境(LAMP+react+vue+redis+mysql+nginx)
  • (C语言)输入自定义个数的整数,打印出最大值和最小值
  • (ISPRS,2023)深度语义-视觉对齐用于zero-shot遥感图像场景分类
  • (草履虫都可以看懂的)PyQt子窗口向主窗口传递参数,主窗口接收子窗口信号、参数。
  • (创新)基于VMD-CNN-BiLSTM的电力负荷预测—代码+数据
  • (附源码)node.js知识分享网站 毕业设计 202038
  • (附源码)springboot 个人网页的网站 毕业设计031623
  • (附源码)springboot宠物管理系统 毕业设计 121654
  • (附源码)ssm户外用品商城 毕业设计 112346
  • (篇九)MySQL常用内置函数
  • (十五)使用Nexus创建Maven私服
  • (一)十分简易快速 自己训练样本 opencv级联haar分类器 车牌识别
  • (转) Face-Resources
  • (转)母版页和相对路径
  • (转)清华学霸演讲稿:永远不要说你已经尽力了
  • (转载)虚幻引擎3--【UnrealScript教程】章节一:20.location和rotation
  • .equals()到底是什么意思?
  • .NET 4.0网络开发入门之旅-- 我在“网” 中央(下)
  • .Net Core 笔试1
  • .NET Framework、.NET Core 、 .NET 5、.NET 6和.NET 7 和.NET8 简介及区别
  • .NET 动态调用WebService + WSE + UsernameToken
  • ??在JSP中,java和JavaScript如何交互?