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

【vue】07.自定义指令

一.什么是自定义指令

在了解什么是自定义指令前,需要知道什么是指令。vue中提供了一套为数据驱动视图更为方便的操作,这些操作被称为指令系统。我们看到的v-为前缀的行内属性,都是指令,它们各自执行特定的功能。此外,Vue还允许开发者创建自定义指令,包括定义全局或局部的指令,这些指令可以在模板中直接操作DOM元素,对 DOM 元素进行底层操作。

二.为什么要使用自定义指令

使用自定义指令可以将复杂的DOM操作封装成可复用的指令,从而提高代码的抽象程度、解耦逻辑,并增强模板的声明式编程能力。简单来说,就是把一些通用的DOM操作封装起来,方便使用。使用自定义指令有一些优点:

  1. 抽象和复用。将复杂的操作封装起来,然后在不同的组件中重复使用,不必每次都重写相同的逻辑。
  2. 简洁。因为自定义指令经与特定 DOM 操作相关的代码从组件的逻辑中分离了出来,将逻辑进行解耦,所以有利于保持组件的简洁性。
  3. 提高可读性。定义指令时最好语义化一些,便于其他开发者阅读代码时,通过指令名称快速理解其作用。
  4. 易于维护。当需要修改或优化 DOM 操作时,只需更新自定义指令的定义,而不必触及每个使用该指令的组件。
  5. 易于共享。自定义指令可以跨组件共享,也就是在多个组件之间可以共享相同的 DOM 操作逻辑。

三.如何使用自定义指令

1.定义全局自定义指令

顾名思义,全局自定义指令就是指在应用的任何组件中都可以使用的指令。要定义一个自定义指令,可以使用.directive方法。

举个例子:

import { createApp } from 'vue';

const app = createApp({});

// 注册一个全局自定义指令 `v-focus`
app.directive('focus', {
  // 当被绑定的元素挂载到 DOM 中时……
  mounted(el) {
    // 聚焦元素
    el.focus();
  }
});

app.mount('#app');

在上面的例子中,我定义了一个名为v-focus的全局指令,它会在元素挂载到DOM后自动聚焦该元素。

再举一个例子:

例子逻辑:

首先创建一个ButtonCounter组件,该组件包含一个按钮和一个计数器,每次点击按钮时,计数器会增加。

<!-- ButtonCounter.vue -->
<template>
  <div>
    <button @click="count++">点击我数量就会增加 {{ count }}</button>
  </div>
</template>

<script setup>
import { ref } from 'vue';

const count = ref(0);
</script>

然后,在主文件中(例如main.jsmain.ts)使用app.component()方法来注册这个全局组件:

// main.js
import { createApp } from 'vue';
import ButtonCounter from './components/ButtonCounter.vue';

const app = createApp({});

// 注册全局组件
app.component('ButtonCounter', ButtonCounter);

app.mount('#app');

2.定义局部自定义指令

局部自定义指令只能在定义它的组件内部使用。在组件的directives选项中定义局部指令。

import { createApp } from 'vue';

const app = createApp({});

app.component('MyComponent', {
  directives: {
    // 注册一个局部自定义指令 `v-focus`
    focus: {
      // 指令的定义
      mounted(el) {
        el.focus();
      }
    }
  }
});

app.mount('#app');

3.在模板中的使用

全局自定义组件的第二个例子在模板中的使用如下:

<!-- 在其他组件的模板中使用 ButtonCounter -->
<template>
  <div>
    <h1>全局注册组件例子</h1>
    <ButtonCounter />
  </div>
</template>

每次点击ButtonCounter组件中的按钮时,计数器的值都会增加。

四.自定义指令的应用场景

自定义指令的应用场景很广泛,这里列出几个典型应用场景。

1.自动聚焦输入框:当页面加载时,自动将焦点设置到某个输入框上,如上面的 v-focus 指令。

2.拖放元素: 创建一个自定义指令来处理元素的拖放功能。

app.directive('draggable', {
  mounted(el) {
    el.draggable = true;
    el.ondragstart = (event) => {
      // 处理拖动逻辑
    };
  }
});

3.懒加载图片: 创建一个自定义指令来延迟加载图片,直到它们进入视口。

app.directive('lazyload', {
  mounted(el) {
    const observer = new IntersectionObserver(
      ([entry]) => {
        if (entry.isIntersecting) {
          el.src = el.dataset.src;
          observer.unobserve(el);
        }
      },
      { threshold: 0.1 }
    );
    observer.observe(el);
  }
});

4.权限控制: 根据用户权限显示或隐藏元素。

app.directive('auth', {
  mounted(el, binding) {
    if (!hasPermission(binding.value)) {
      el.parentNode.removeChild(el);
    }
  }
});

5.全屏切换: 创建一个指令来切换元素的全屏状态。

app.directive('fullscreen', {
  mounted(el, binding) {
    if (binding.value) {
      el.requestFullscreen();
    } else {
      document.exitFullscreen();
    }
  }
});

6.格式化输入: 对输入框的值进行格式化,例如货币格式化。

app.directive('format-currency', {
  updated(el, binding) {
    const value = binding.value;
    el.value = new Intl.NumberFormat('en-US', {
      style: 'currency',
      currency: 'USD',
    }).format(value);
  }
});

到此结束。


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

相关文章:

  • 【优选算法篇】前缀之序,后缀之章:于数列深处邂逅算法的光与影
  • 谷歌云GCP基础概念讲解
  • 计算机网络IP地址分类,子网掩码,子网划分复习资料
  • RagFlow本地部署使用
  • 【制造业&流水线】流水线水泥袋检测系统源码&数据集全套:改进yolo11-HSPAN
  • VsCode | 修改内置字体为JetBrains Mono NL
  • GitHub Copilot将支持来自Anthropic、Google和OpenAI的模型
  • 双指针——对撞指针与左右指针
  • Twitter网页版怎么登录?详细步骤与常见问题解答
  • kotlin的this和it用法
  • ffmpeg视频滤镜:膨胀操作-dilation
  • 算法:常见位运算技巧总结
  • Dirichlet分布生成联邦学生non-iid数据
  • css实现背景色的斑马条效果
  • 如何用李萨如图形测正弦信号的频率?若不使用李萨如图形,如何用示波器测交流信号频率?
  • PHP内存马:不死马
  • 微信小程序如何实现地图轨迹回放?
  • 地球上的中国:世界地图概览
  • Go中的泛型
  • NFS服务器作业
  • Linux云计算 |【第五阶段】CLOUD-DAY1
  • 字母象形与hand的不同解构
  • 【机器学习】揭秘XGboost:高效梯度提升算法的实践与应用
  • 「C/C++」C++ 设计模式 之 单例模式(Singleton)
  • 怎么实现电脑控制100台手机,苹果手机群控系统不用越狱实现新突破
  • GitHub Actions的 CI/CD