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

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 切换样式或恢复原始样式。
在元素卸载时,移除所有绑定的事件处理函数。


http://www.kler.cn/a/317208.html

相关文章:

  • 量化交易系统开发-实时行情自动化交易-3.4.2.2.Okex交易数据
  • AI大模型开发架构设计(18)——基于大模型构建企业知识库案例实战
  • Linux 函数在多个地方被同时调用时,函数中的变量如何管理,确保互不影响
  • 除了 Mock.js,前端还有更方便的 Mock 数据工具吗?
  • Axure网络短剧APP端原型图,竖屏微剧视频模版40页
  • 3D绘制动态爱心Matlab
  • 平衡二叉树(AVL树):原理、常见算法及其应用
  • cccccccccccc
  • Qt_布局管理器
  • 【漏洞复现】HIKVISION 视频编码设备接入网关 showFile.php 任意文件下载漏洞
  • tomcat 配置jenkins_home 目录
  • 动态时间【JavaScript】
  • 使用【Sa-Token】实现Http Basic 认证
  • 输电线塔目标检测数据集yolo格式该数据集包括2644张输电线塔高清图像,该数据集已经过yolo格式标注,具有完整的txt标注文件和yaml配置文件。
  • 论文阅读--Planning-oriented Autonomous Driving(二)
  • C++堆(优先队列)priority_queue
  • 删除topic提示admin token
  • The NCCoE’s Automation of the CMVP
  • 【Oauth2整合gateway网关实现微服务单点登录】
  • k8s云平台部署文档
  • 【MySQL】使用C语言连接数据库
  • Http-浏览器发出⼀个请求到收到响应经历了哪些步骤?
  • 如何使用GLib的单向链表GSList
  • 【软考】cpu的功能
  • Linux环境的JDK安装
  • 【爬虫工具】小红书评论高级采集软件