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

写一个Vue2和vue3的自定义指令(以复制指定作为示例)

文章目录

  • 一、自定义指令是什么?
  • 二、自定义指令有啥用?
  • 三、自定义指令怎么用?
    • 1.自定义指令的参数
    • 2.自定义指令的钩子函数
      • (1)五个钩子函数的说明
      • (2)钩子函数的参数(主要参数:el和value)
    • 3.动态参数和修饰符
      • (1)参数的使用
      • (2)动态参数的使用
      • (3)修饰符
  • 四、完整的vue2自定义指令使用
    • 1. 在src下面创建directive文件夹(表示是自定义文件夹)
    • 2. 新建文件copy.js(表示是个复制的自定义指令)
    • 3. copy.js 的完整代码
    • 4 .main.js
  • 五、局部指令(了解)
  • 六、完整的vue3自定义指令使用(全局和局部)
    • 1. 指令钩子
    • 2. 钩子参数
    • 3. 全局自定义组件的使用
      • (1) 在src下面创建directive文件夹(表示是自定义文件夹)
      • (2)新建文件copy.js(表示是个复制的自定义指令)
      • (3)copy.ts 的完整代码
      • (4)main.ts
    • 4. setup函数的局部组件使用
    • 5. setup script的局部组件使用
    • 6. setup 函数和setup script的局部指令使用 代码图

一、自定义指令是什么?

直接看官网的说明:带有v- 前缀的特殊 attribute(属性)

二、自定义指令有啥用?

作用:一个指令的任务是在其表达式的值变化时响应式地更新 DOM

<p v-if="seen">现在你看到我了</p>

v-if 指令会基于表达式 seen 的值的真假来移除/插入该 < p> 元素。

三、自定义指令怎么用?

1.自定义指令的参数

/*
* {string} id 自定义指令的名称
* {Function | Object} [definition] 自定义指令的回调函数
*/
Vue.directive( id, [definition] )

2.自定义指令的钩子函数

(1)五个钩子函数的说明

// 注册一个全局自定义指令 `my-directive`(Vue.directive注册自定义指令)
Vue.directive('my-directive', {bind(el, binding, vnode) {}, // 当指令绑定到元素上时调用inserted(el) {}, // 当绑定元素插入到 DOM 中时调用update(el, binding, vnode, oldVnode) {} // 在包含组件的 VNode 更新时调用componentUpdated(el, binding, vnode, oldVnode) {} // 在包含组件的 VNode 及其子 VNode 全部更新后调用unbind(el, binding, vnode) {} // 当指令与元素解绑时调用
});

(2)钩子函数的参数(主要参数:el和value)

el:指令所绑定的元素,可以用来直接操作 DOM。binding:一个对象,包含以下 property: name:指令名,不包括 v- 前缀。value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2。
oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
expression:字符串形式的指令表达式。例如 v-my-directive=“1 + 1” 中,表达式为 “1 + 1”。
arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 “foo”。
modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }。
vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。
oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。

3.动态参数和修饰符

理论说完,直接看demo

(1)参数的使用

<div v-copy="value1的值"> 
// binding 参数会是一个这样的对象
{arg: 'copy',modifiers: {},value: /* `value1` 的值 */,oldValue: /* 上一次更新时 `value1` 的值 */
}
<div v-example:foo.bar="value2">
// 你将获得的binding 参数会是一个这样的对象
{arg: 'foo',modifiers: { bar: true },value: /* `value2` 的值 */,oldValue: /* 上一次更新时 `value2` 的值 */
}

(2)动态参数的使用

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

(3)修饰符

同点击事件这种使用修饰符

// 提交事件使用

<form @submit.prevent="onSubmit">...</form>

// 自定义指令使用

<button v-copy.prevent="baz">...</button>
// v-copy 是定义的自定义名称
// prevent 是修饰符
// baz 是自定义的value

四、完整的vue2自定义指令使用

1. 在src下面创建directive文件夹(表示是自定义文件夹)

2. 新建文件copy.js(表示是个复制的自定义指令)

3. copy.js 的完整代码

import Vue from 'vue'
import { Message } from 'view-design' // 根据你使用的不同框架替换提示语句
// 注册一个全局自定义复制指令 `v-copy`
Vue.directive('copy', {// 参数1 ‘el’ 就是操作的dom,第二个参数就是binding,获取里面的属性value,也就是要复制的值bind (el, { value }) {el.$value = valueel.handler = () => {el.style.position = 'relative'if (!el.$value) {// 值为空的时候,给出提示alert('无复制内容')return}// 动态创建 textarea 标签const textarea = document.createElement('textarea')// 将该 textarea 设为 readonly 防止 iOS 下自动唤起键盘,同时将 textarea 移出可视区域textarea.readOnly = 'readonly'textarea.style.position = 'absolute'textarea.style.top = '0px'textarea.style.left = '-9999px'textarea.style.zIndex = '-9999'// 将要 copy 的值赋给 textarea 标签的 value 属性textarea.value = el.$value// 将 textarea 插入到 el 中el.appendChild(textarea)// 兼容IOS 没有 select() 方法if (textarea.createTextRange) {textarea.select() // 选中值并复制} else {textarea.setSelectionRange(0, el.$value.length)textarea.focus()}const result = document.execCommand('Copy')if (result) Message.success('复制成功')el.removeChild(textarea)}el.addEventListener('click', el.handler) // 绑定点击事件},// 当传进来的值更新的时候触发componentUpdated (el, { value }) {el.$value = value},// 指令与元素解绑的时候,移除事件绑定unbind (el) {el.removeEventListener('click', el.handler)}
})

4 .main.js

因为在copy.js中

import './directive/copy'

五、局部指令(了解)

全局指令:通过 Vue.directive() 函数注册一个全局的指令。
局部指令:通过组件的 directives 属性,对该组件添加一个局部的指令
注意点:==directives 和 methods 确实是同级的配置项,别放在methods里面了。==其他使用同全局指令。

directives: {copy: {// 指令的定义inserted: function (el) {// 复制逻辑,不在重复了}}
}

六、完整的vue3自定义指令使用(全局和局部)

1. 指令钩子

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

2. 钩子参数

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。prevVnode:代表之前的渲染中指令所绑定元素的 VNode。仅在 beforeUpdate 和 updated 钩子中可用。

3. 全局自定义组件的使用

(1) 在src下面创建directive文件夹(表示是自定义文件夹)

(2)新建文件copy.js(表示是个复制的自定义指令)

(3)copy.ts 的完整代码

import { DirectiveBinding } from 'vue';
import { message } from 'ant-design-vue'
// 注册一个全局自定义复制指令 `v-copy`
const copy = {// 在绑定元素的父组件及他自己的所有子节点都挂载完成后调用mounted(el: HTMLElement, binding: DirectiveBinding) {el.addEventListener('click', () => {const textToCopy = binding.value;if (textToCopy) {// 如果支持Clipboard APIif (navigator.clipboard && navigator.clipboard.writeText) {navigator.clipboard.writeText(textToCopy).then(() => {message.success('复制成功!')}).catch(err => {message.error(err + '复制失败!')});} else {// 不支持创建一个临时的 textarea 元素来实现复制功能const textarea = document.createElement('textarea');textarea.value = textToCopy;textarea.style.position = 'fixed';document.body.appendChild(textarea);textarea.focus();textarea.select();try {document.execCommand('copy');message.success('复制成功!')} catch (err) {message.error(err + '复制失败!')}document.body.removeChild(textarea);}}});},// 绑定元素的父组件卸载后调用unmounted(el: HTMLElement) {el.removeEventListener('click', () => {});}
}
export default copy

(4)main.ts

import { createApp } from 'vue'
import App from './App.vue'
import copy from './directive/copy'
const app = createApp(App)
app.directive('copy', copy);
app.mount('#app')

4. setup函数的局部组件使用

<template><div><input v-model="text" placeholder="Enter text to copy" /><button v-copy="text">Copy Text</button></div>
</template><script>
import { ref } from 'vue';export default {setup() {const text = ref('');// 定义局部指令const copyDirective = {mounted(el, binding) {el.addEventListener('click', () => {});},unmounted(el) {el.removeEventListener('click', () => {});}};return {text,directives: {copy: copyDirective}};}
};
</script>

5. setup script的局部组件使用

<template><divvue
<template><div><input v-model="text" placeholder="Enter text to copy" /><button v-copy="text">Copy Text</button></div>
</template><script setup>
import { ref, directive } from 'vue';// 定义局部指令
const copyDirective = {mounted(el, binding) {el.addEventListener('click', () => {});},unmounted(el) {el.removeEventListener('click', () => {});}
};// 注册局部指令
const directives = {copy: copyDirective
};// 定义响应式数据
const text = ref('');
</script>

6. setup 函数和setup script的局部指令使用 代码图

在这里插入图片描述

相关文章:

写一个Vue2和vue3的自定义指令(以复制指定作为示例)

文章目录 一、自定义指令是什么&#xff1f;二、自定义指令有啥用&#xff1f;三、自定义指令怎么用&#xff1f;1.自定义指令的参数2.自定义指令的钩子函数&#xff08;1&#xff09;五个钩子函数的说明&#xff08;2&#xff09;钩子函数的参数(主要参数&#xff1a;el和valu…...

MySQL —— 聚合查询,分组查询 与 联合查询

聚合函数 常见的统计总数、计算平局值等操作&#xff0c;可以使用聚合函数来实现&#xff0c;常见的聚合函数有&#xff1a; 函数说明count()统计数据总数sum()求和avg()求平均值max()求最大值min()求最小值 注意凡是涉及运算的&#xff0c;数据库会自动掉 NULL 值 注意NULL …...

Spring声明式事务失效场景

Spring声明式事务失效场景 背景搭建测试环境测试事务失效场景Transactional 注解标注在 private 方法上异常被 catch 了&#xff0c;事务失效方法抛出的是受检异常&#xff0c;事务也会失效事务传播行为配置不合理导致事务失效 背景 Spring 针对 Java Transaction API (JTA)、…...

基于SpringBoot+UniAPP宠物食品外卖点单小程序的设计与实现》

✅博主简介&#xff1a;Java 全栈开发工程师&#xff0c;抖音优质技术创作者&#xff0c;日常分享实用的前端、后端、运维开发技术。 ✅技术栈&#xff1a;Java、SpringBoot、Vue、React、Node.js、Nest.js、Nuxt.js、uni-app ✅技术擅长&#xff1a;计算机毕设选题、开题报告、…...

ssrf 内网访问 伪协议 读取文件 端口扫描

SSRF&#xff08;Server-Side Request Forgery&#xff0c;服务器侧请求伪造&#xff09;是一种利用服务器发起网络请求的能力来攻击内网资源或执行其他恶意活动的技术。SSRF可以用于访问通常不可由外部直接访问的内网资源&#xff0c;读取文件&#xff0c;甚至进行端口扫描。以…...

发布包到npm

目录 注册npm账号 创建包 登录npm 上架包 更新包 删除包 注册npm账号 首先注册npm账号&#xff1a;npm | Sign Up (npmjs.com) 创建包 可以在桌面上新建一个文件夹&#xff1a;文件夹名随便起&#xff0c;但是别跟npm已经上架的包名重复了 可以通过下面的指令查看&…...

Python | Leetcode Python题解之第324题摆动排序II

题目&#xff1a; 题解&#xff1a; def quickSelect(a: List[int], k: int) -> int:seed(datetime.datetime.now())shuffle(a)l, r 0, len(a) - 1while l < r:pivot a[l]i, j l, r 1while True:i 1while i < r and a[i] < pivot:i 1j - 1while j > l an…...

IGModel——提高基于 GNN与Attention 机制的方法在药物发现中的实用性

导言 深度学习在药物发现&#xff08;发现治疗药物&#xff09;领域的应用以及传统方法面临的挑战。 药物&#xff08;尤其是我们将在本文中讨论的被称为抑制剂的药物&#xff09;通过与在人体中发挥不良功能的蛋白质结合并改变这些蛋白质的功能来发挥治疗效果。因此&#xf…...

AArch64中的寄存器

目录 通用寄存器 其他寄存器 系统寄存器 通用寄存器 大多数A64指令在寄存器上操作。该架构提供了31个通用寄存器。 每个寄存器可以作为64位的X寄存器&#xff08;X0..X30&#xff09;使用&#xff0c;或者作为32位的W寄存器&#xff08;W0..W30&#xff09;使用。这两种是查…...

树莓派Pico 2来了

这两天开源圈的大事之一&#xff0c;就是树莓派基金会发布了树莓派Pico 2。 帖子原文&#xff1a;Raspberry Pi Pico 2, our new $5 microcontroller board, on sale now 总结一些关键信息&#xff1a; 产品发布&#xff1a;Raspberry Pi Pico 2 是 Raspberry Pi 基金会推出的…...

LeetCode面试题Day7|LeetCode135 分发糖果、LeetCode42 接雨水

题目1&#xff1a; 指路&#xff1a; . - 力扣&#xff08;LeetCode&#xff09;135 分发糖果 思路与分析&#xff1a; 给n个孩子按照评分给糖果&#xff0c;要求有二&#xff0c;其一为每个孩子最少有一颗糖果&#xff1b;其二为相邻孩子评分更高的糖果越多。那么在这里第…...

[免费]适用于 Windows 10 的十大数据恢复软件

Windows 10 是 Microsoft 开发的跨平台和设备应用程序操作系统。它启动速度更快&#xff0c;具有熟悉且扩展的“开始”菜单&#xff0c;甚至可以在多台设备上以新的方式工作。因此&#xff0c;Windows 10 非常受欢迎&#xff0c;我们用它来保存照片、音乐、文档和更多文件。但有…...

Win11+docker+vscode配置anomalib并训练自己的数据(3)

在前两篇博文中,我使用Win11+docker配置了anomalib,并成功的调用了GPU运行了示例程序。这次我准备使用anomalib训练我自己的数据集。 数据集是我在工作中收集到的火腿肠缺陷数据,与MVTec等数据不同,我的火腿肠数据来源于多台设备和多个品种,因此,它们表面的纹理与颜色差异…...

Java | Leetcode Java题解之第332题重新安排行程

题目&#xff1a; 题解&#xff1a; class Solution {Map<String, PriorityQueue<String>> map new HashMap<String, PriorityQueue<String>>();List<String> itinerary new LinkedList<String>();public List<String> findItine…...

招聘公告|健安环保科技(广东)有限公司

招聘岗位&#xff1a;销售经理 岗位职责&#xff1a; 对PCB线路板和电镀行业的客户&#xff0c;推广针对镀锡漂洗水的低浓度锡回收技术(投资运营或设备销售)&#xff0c;并销售无耗材材的电镀智能过滤设备&#xff0c;达成销售目标; 任职要求&#xff1a; 1、大专以上学历&…...

小程序的安全设计

小程序的安全设计 安全指引 | 微信开放文档 (qq.com) 开发原则与注意事项 本文档整理了部分小程序开发中常见的安全风险和漏洞,用于帮助开发者在开发环节中发现和修复相关漏洞,避免在上线后对业务和数据造成损失。 开发者在开发环节中必须基于以下原则: 互不信任原则,不要…...

【Android】网络技术知识总结之WebView,HttpURLConnection,OKHttp,XML的pull解析方式

文章目录 webView使用步骤示例 HttpURLConnection使用步骤示例GET请求POST请求 okHttp使用步骤1. 添加依赖2. 创建OkHttpClient实例3. 创建Request对象构建请求4. 发送请求5. 获取响应 Pull解析方式1. 准备XML数据2. 创建数据类3. 使用Pull解析器解析XML webView WebView 是 An…...

Kubernetes—k8s集群存储卷(pvc存储卷)

目录 一、PVC 和 PV 1.PV 2.PVC 3.StorageClass 4.PV和PVC的生命周期 二、实操 1.创建静态pv 1.配置nfs 2.创建pv 3.创建pvc 4.结合pod&#xff0c;将pv、pvc一起运行 2.创建动态pv 1.上传 2.创建 Service Account&#xff0c;用来管理 NFS Provisioner 在 k8s …...

用网格大师转换的3D Tiles数据,在进行了顶点重建后,尝试加载到Cesium中却无法显示内容。应该如何解决这一问题?

答&#xff1a; 建议首先尝试使用DasViewer来打开并检查这个3D Tiles的json文件。DasViewer能够迅速加载并显示3D Tiles数据&#xff0c;可以帮助快速验证数据是否完整且格式正确。 网格大师是一款能够解决实景三维模型空间参考、原点、瓦块大小不统一&#xff0c;重叠区域处理…...

display:flex布局,最简单的案例

1. 左右贴边 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><style>#parent{width: 800px;background: red;height: 200px;display: flex;justify-content: space-between…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来

一、破局&#xff1a;PCB行业的时代之问 在数字经济蓬勃发展的浪潮中&#xff0c;PCB&#xff08;印制电路板&#xff09;作为 “电子产品之母”&#xff0c;其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透&#xff0c;PCB行业面临着前所未有的挑战与机遇。产品迭代…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络&#xff0c;将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具&#xff0c;支持 Chrome、Firefox、Safari 等主流浏览器&#xff0c;提供多语言 API&#xff08;Python、JavaScript、Java、.NET&#xff09;。它的特点包括&a…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

GitHub 趋势日报 (2025年06月08日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题&#xff1a;3564. 季节性销售分析 题目&#xff1a; 表&#xff1a;sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接&#xff1a;3403. 从盒子中找出字典序最大的字符串 I 代码如下&#xff1a; class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域&#xff0c;向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能&#xff0c;能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作&#xff0c;并通过具体…...