Vue3: 自定义指令实战

文章介绍了如何在Vue3中定义和使用自定义指令,特别是针对长按事件的处理。通过`install`方法注册指令,利用`mounted`钩子添加事件监听器,设置计时器并在满足条件时执行回调函数。示例展示了如何在组件上应用自定义的`v-longpress`指令来触发特定的操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Vue3自定义指令

定义指令步骤

定义install方法

app.use(directive,{time: 500}); 会调用 install方法, 第一是app对象,第二个是参数对象。

import { App } from 'vue';

export default {
  install(
    app: App,
    options = {
      time: 1500,
    }
  ) {

}

自定义指定参数对象

  • el:指令绑定到的元素。这可以用于直接操作 DOM。
  • binding
    • value:传递给指令的值。例如在 v-my-directive=“1 + 1” 中,值是 2。
      如果是函数则是函数的返回值。
    • oldValue 之前的值,仅在 beforeUpdate 和 updated 中可用。无论值是否更改,它都可用。
    • arg: 例如在 v-my-directive:foo 中,参数是 “foo”。
    • modifiers:一个包含修饰符的对象 (如果有的话)。例如在 v-my-directive.foo.bar 中,修饰符对象是 { foo: true, bar: true }。
    • instance:使用该指令的组件实例。
    • dir:指令的定义对象。
  • vnode: 代表绑定元素的底层 VNode。
  • prevNode:之前的渲染中代表指令所绑定元素的 VNode。仅在 beforeUpdate 和 updated 钩子中可用。

举例

<div v-example:foo.bar="baz">

{
  arg: 'foo',
  modifiers: { bar: true },
  value: /* `baz` 的值, 如果是函数, 则是函数的返回值 */,
  oldValue: /* 上一次更新时 `baz` 的值 */
}

自定义指定动态参数

<div v-example:[arg]="value"></div>

示例

指令示例


export default {
  install(
    app: App,
    options = {
      time: 1500,
    }
  ) {
    app.directive('longpress', {
      mounted(el, binding) {
        if (typeof binding.value.fn !== 'function') {
      // // 将警告传递给控制台
      const warn = `[longpress:] provided expression '${binding.value}' is not afunction, but has to be `;
      console.warn(warn);
    } else {
      // 定义变量
      let pressTimer: ReturnType<typeof setTimeout> | null = null; // 定义空 定时器;
      // 定义函数处理程序
      const handler = () => {
        // 执行传递给指令的方法
        if (binding.value.fn) {
          binding.value.fn(binding.value.arg);
        }
      };
      // 创建计时器( 1秒后执行函数 )
      const start = (e: MouseEvent | TouchEvent) => {
        // 下列事件不执行1.不是鼠标左键2.单击事件  (3.没有传入长按时间 ?? 有默认)
        if ((<MouseEvent>e).button !== 0 && e.type === 'click') {
          return;
        }
        if (pressTimer === null) {
          pressTimer = setTimeout(() => {
            // 执行函数
            handler();
          }, options.time);
        }
      };
      // 取消计时器
      const cancel = () => {
        // 检查计时器是否有值
        if (pressTimer !== null) {
          clearTimeout(pressTimer);
          pressTimer = null;
        }
      };

      // 添加事件监听器
      el.addEventListener('mousedown', start);
      el.addEventListener('touchstart', start);
      // 取消计时器
      el.addEventListener('click', cancel);
      el.addEventListener('mouseout', cancel);
      el.addEventListener('touchend', cancel);
      el.addEventListener('touchcancel', cancel);
    }
    });
  },
};

指令使用

              ...
                <component
                :is="wp.name"
                v-longpress="{ fn: longPressDrag, arg: wp }"
                class="widgetCls"
                style="left: 50%"
              ></component>
              ...
      // setup
      const longPressDrag = (w: WidgetPlugin) => {
        // 如果小组件是锁定状态,长按后允许拖动
        if (!w.draggable) {
          return w;
        }
        return null;
      };
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西魏陶渊明

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值