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

vue中的自定义指令

前言

说到 vue 中的自定义指令,相信大家都不陌生。在官网中是这么说的,除了核心功能默认内置的指令 (v-modelv-show),vue 也允许注册自定义指令。那什么时候会用到自定义指令呢?代码复用和抽象的主要形式是组件。然而,有的情况下,你仍然需要对普通 dom 元素进行底层操作,这时候就会用到自定义指令。

在这里插入图片描述


自定义指令

自定义指令分为:全局自定义指令,局部自定义指令。它有两个参数:参数1:指令的名称;参数2:是一个对象,这个对象身上,有钩子函数。

全局自定义指令

通过 Vue.directive() 函数注册一个全局的指令

// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {// 当被绑定的元素插入到 DOM 中时……inserted: function (el) {// 聚焦元素el.focus()}
})

main.js 中引入

import focus from '@/utils/focus'

局部自定义指令

通过组件的 directives 属性,对该组件添加一个局部的指令

directives: {focus: {// 指令的定义inserted: function (el) {el.focus()}}
}

然后你可以在组件中任何元素上使用 v-focus 自定义的指令,如下:

<input v-focus/>

批量注册指令

src 目录下新建文件夹(directives/index.js)管理各个子文件(自定义指令文件),然后在根文件(index.js)中对外暴露 api,最后在 main.js 中引入并注册,这样做的好处是统一管理后,后期比较好维护,而且会比较清晰。

文件目录: src/directives/index.js

import Vue from 'vue';
import copy from './modules/copy';//引入自定义指令
const directives = {// 自定义指令copy,
};
export default {install(Vue) {Object.keys(directives).forEach(key => Vue.directive(key, directives[key]))}
}

main.js 中引入并注册

import Directives from '@/directives';
Vue.use(Directives);

钩子函数

bind

只调用一次,指令第一次绑定到元素时调用。

inserted

被绑定元素插入父节点时调用。

update

所在组件的虚拟节点更新时调用。

componentUpdated

所在组件的虚拟节点及其子虚拟节点全部更新时调用。

unbind

只调用一次,指令与元素解绑时调用。


实例

看到这里,你可能对自定义指令已经有了大概的了解和认识,那可能有的同学要问了,在实际的开发中,自定义指令有什么使用场景吗?下面分享在开发中常用的使用场景。


1. 复制粘贴指令

文件目录:src/directives/modules/copy.js

export default {bind(el, {value}) {el.$value = value;el.handler = () => {if (!el.$value) {// 值为空的时候,给出提示console.log('无复制内容');return;}const textarea = document.createElement('textarea');// 将该textarea设为readonly,防止iOS下自动唤起软键盘textarea.readOnly = 'readonly';textarea.style.position = 'absolute';textarea.style.left = '-9999px';// 将要copy的值赋给textarea标签的value属性textarea.value = el.$value;// 将textarea插入到body中document.body.appendChild(textarea);// 选中值并复制textarea.select();const result = document.execCommand('Copy');if (result) {console.log('复制成功');}// 赋值成功后,将textarea移除掉document.body.removeChild(textarea);};// 绑定点击事件el.addEventListener('click', el.handler);},componentUpdated(el, {value}) {el.$value = value;},// 指令与元素解绑的时候,移除事件绑定unbind(el) {el.removeEventListener('click', el.handler);}
}

组件中使用

<template><div><button v-copy="copyText">复制</button></div>
</template>
<script>
export default {data() {return {copyText: "等待被复制的内容",};},
};
</script>

实现效果

在这里插入图片描述


2. 长按指令

文件目录:src/directives/modules/longpress.js

export default {bind(el, {value}) {if ('function' !== typeof value) {throw 'callback must be a function';}let pressTimer = null;let start = e => {if ('click' === e.type && 0 !== e.button) {return;}if (null === pressTimer) {pressTimer = setTimeout(() => {// 执行函数value(e);}, 1000);}};let cancel = e => {if (null !== pressTimer) {clearTimeout(pressTimer);pressTimer = null;}};// 添加事件监听器el.addEventListener('mousedown', start);el.addEventListener('mouseout', cancel);el.addEventListener('click', cancel);el.addEventListener('touchstart', start);el.addEventListener('touchend', cancel);el.addEventListener('touchcancel', cancel);}
}

组件中使用

<template><div><button v-longpress="longpress">长按我</button></div>
</template>
<script>
export default {methods: {longpress() {alert("触发了长按");},},
};
</script>

实现效果

在这里插入图片描述


3. 输入框防抖指令

文件目录:src/directives/modules/debounce.js

export default {inserted(el, {value}) {if ('function' !== typeof value) {throw 'directive value must be function';}let timer;el.addEventListener('keyup', () => {timer && clearTimeout(timer);timer = setTimeout(() => {value && value();}, 1000);});}
}

组件中使用

<template><div><button v-longpress="longpress">长按我</button></div>
</template>
<script>
export default {methods: {longpress() {alert("触发了长按");},},
};
</script>

实现效果

在这里插入图片描述


4. 输入框自动聚焦指令

文件目录:src/directives/modules/focus.js

export default {inserted(el, {value}) {// 聚焦元素el.focus()}
}

组件中使用

<template><div><input v-focus type="text" /></div>
</template>

实现效果

在这里插入图片描述


5. 全屏指令

文件目录:src/directives/modules/fullScreen.js

export default {bind(el, binding) {if (binding.modifiers.icon) {if (el.hasIcon) return// 创建全屏图标const iconElement = document.createElement('i')iconElement.setAttribute('class', 'el-icon-full-screen')iconElement.setAttribute('style', 'margin-left:5px')el.appendChild(iconElement)el.hasIcon = true}el.style.cursor = el.style.cursor || 'pointer'// 监听点击全屏事件el.addEventListener('click', () => handleClick())}
}function handleClick() {let FullScreen = falselet element = document.documentElement;if (FullScreen) {if (document.exitFullscreen) {document.exitFullscreen();} else if (document.webkitCancelFullScreen) {document.webkitCancelFullScreen();} else if (document.mozCancelFullScreen) {document.mozCancelFullScreen();} else if (document.msExitFullscreen) {document.msExitFullscreen();}} else {if (element.requestFullscreen) {element.requestFullscreen();} else if (element.webkitRequestFullScreen) {element.webkitRequestFullScreen();} else if (element.mozRequestFullScreen) {element.mozRequestFullScreen();} else if (element.msRequestFullscreen) {element.msRequestFullscreen();}}FullScreen = !FullScreen;
}

组件中使用

<template><div><span v-fullScreen.icon>全屏</span></div>
</template>

实现效果

在这里插入图片描述


6. 文字超出展示省略号指令

文件目录:src/directives/modules/ellipsis.js

export default {bind(el, binding) {console.log(el,binding);el.style.width = binding.arg || 100 + 'vw'el.style.whiteSpace = 'nowrap'el.style.overflow = 'hidden';el.style.textOverflow = 'ellipsis';}
}

组件中使用

<template><div><div v-ellipsis>给你一首诗的时间,坐在炉火边,捧着诗卷阅读,听不见大摆钟的摇摆,远离岁月的尘埃</div></div>
</template>

实现效果

在这里插入图片描述


7. 拖拽指令

文件目录:src/directives/modules/drag.js

export default {bind(el, binding) {document.onselectstart = function () {return false //禁止选择网页上的文字}el.style.cursor = 'move' // 图标el.style.position = 'absolute'el.onmousedown = function (ev) {// 用元素距离视窗的X、Y坐标,减去el元素最近的相对定位父元素的left、top值var sX = ev.clientX - el.offsetLeftvar sY = ev.clientY - el.offsetTopdocument.onmousemove = function (ev) {var eX = ev.clientX - sXvar eY = ev.clientY - sY// 不断地更新元素的left、top值el.style.left = eX + 'px'el.style.top = eY + 'px'}document.onmouseup = function () {// 清除mousemove事件document.onmousemove = null}}}
}

组件中使用

<template><div><div class="box" v-drag>拖拽</div></div>
</template>
<script>
export default {data() {return {};},
};
</script>
<style scoped>
.box {width: 100px;height: 100px;background: cadetblue;text-align: center;line-height: 100px;color: #fff;
}
</style>

实现效果

在这里插入图片描述


8. 字符串整形指令

文件目录:src/directives/modules/format.js

export default {bind(el, binding, vnode) {const {value,modifiers} = bindingif (!value) returnlet formatValue = valueif (modifiers.toFixed) {formatValue = value.toFixed(2)}console.log(formatValue)if (modifiers.price) {formatValue = formatNumber(formatValue)}el.innerText = formatValue},
}function formatNumber(num) {num += '';let strs = num.split('.');let x1 = strs[0];let x2 = strs.length > 1 ? '.' + strs[1] : '';var rgx = /(\d+)(\d{3})/;while (rgx.test(x1)) {x1 = x1.replace(rgx, '$1' + ',' + '$2');}return x1 + x2
}

组件中使用

<template><div><div v-format.toFixed.price="123456789"></div><div v-format.toFixed="123.4567"></div></div>
</template>

实现效果

在这里插入图片描述

持续更新中...

相关文章:

vue中的自定义指令

前言 说到 vue 中的自定义指令&#xff0c;相信大家都不陌生。在官网中是这么说的&#xff0c;除了核心功能默认内置的指令 (v-model 和 v-show)&#xff0c;vue 也允许注册自定义指令。那什么时候会用到自定义指令呢&#xff1f;代码复用和抽象的主要形式是组件。然而&#xf…...

技术分享及探讨

前言 很高兴给大家做一个技术分享及探讨。 下面给大家分享几个工作遇到有趣的例子。 docker docker 进程 现象 ​ 客户的模型导入到BML平台发布预测服务后&#xff0c;模型本身是用django提供的支持。按照本地docker的方式进行调试&#xff0c;kill掉django的进程修改代码…...

人工智能AI

AI 模型。它使用深度神经网络&#xff0c;从数十亿或数万亿个单词中学习&#xff0c;能够生成任何主题或领域的文本。它可以执行各种自然语言任务&#xff0c;如分类、总结、翻译、生成和对话。 大语言模型开发建立在4个核心思想上&#xff1a; 模型 – Models 提示词 - Prompt…...

2022天梯赛补题

题目详情 - L2-041 插松枝 (pintia.cn) 思路&#xff1a;模拟 背包就是个栈&#xff0c;开个stack解决流程思路是&#xff0c;每次取推进器前&#xff0c;尽可能拿背包的&#xff0c;背包拿到不可以时&#xff0c;跳出拿推进器时判断&#xff1a; 如果背包装得下&#xff0c;…...

字节跳动测试岗面试挂在2面,复盘后,我总结了失败原因,决定再战一次...

先说下我基本情况&#xff0c;本科不是计算机专业&#xff0c;现在是学通信&#xff0c;然后做图像处理&#xff0c;可能面试官看我不是科班出身没有问太多计算机相关的问题&#xff0c;因为第一次找工作&#xff0c;字节的游戏专场又是最早开始的&#xff0c;就投递了&#xf…...

Nodejs实现通用的加密和哈希算法(MD5、SHA1、Hmac、AES、Diffie-Hellman、RSA),crypto模块详解

crypto crypto模块的目的是为了提供通用的加密和哈希算法(hash)。用纯JavaScript代码实现这些功能不是不可能,但速度会非常慢。Nodejs用C/C++实现这些算法后,通过cypto这个模块暴露为JavaScript接口,这样用起来方便,运行速度也快。 MD5和SHA1 MD5是一种常用的哈希算法,…...

测试行业3年经验,从大厂裸辞后,面试阿里、字节全都一面挂,被面试官说我的水平还不如应届生

测试员可以先在大厂镀金&#xff0c;以后去中小厂毫无压力&#xff0c;基本不会被卡&#xff0c;事实果真如此吗&#xff1f;但是在我身上却是给了我很大一巴掌... 所谓大厂镀金只是不卡简历而已&#xff0c;如果面试答得稀烂&#xff0c;人家根本不会要你。况且要不是大厂出来…...

安卓悬浮窗口,  丝滑双指缩放视频窗口

最重要的事情说前面: demo源码:https://github.com/5800LDW/ProjectFloatingWindow前言:1.跨应用的浮动窗口在网上很多资料, 就不细说了。2.双指缩放View 也很多资料, 可参考:https://blog.csdn.net/zxq614/article/details/88873729正文下面进入正题, 如何把上述结合起来, 下面…...

300左右哪款蓝牙耳机适合学生用?四款便宜质量好的蓝牙耳机推荐

近年来&#xff0c;随着蓝牙耳机的发展&#xff0c;不管是音质、外观、佩戴还是降噪都有了很大的提升。但是我们在入手蓝牙耳机时&#xff0c;最好还是根据预算和需求入手。在此&#xff0c;我来给预算在三百内的朋友推荐几款便宜质量好的蓝牙耳机&#xff0c;可以当个参考。 …...

桥梁设计模式

介绍 Java桥梁模式(也称桥接模式)(Bridge Pattern)是一种设计模式,它将抽象和实现分离,使它们可以独立地变化.它通过一个大类或者一系列紧密关联的类拆分成两个独立的层次结构来实现这种分离,其中一个层次结构包含抽象类或接口,另一个层次结构包含实现类.桥梁模式使得抽象类和…...

【华为OD机试 2023最新 】 新员工座位(C++)

文章目录 题目描述输入描述输出描述用例题目解析C++题目描述 工位由序列F1,F2…Fn组成,Fi值为0、1或2。其中0代表空置,1代表有人,2代表障碍物。 1、某一空位的友好度为左右连续老员工数之和, 2、为方便新员工学习求助,优先安排友好度高的空位, 给出工位序列,求所有空…...

蓝桥杯刷题第二十二天

第一题&#xff1a;受伤的皇后题目描述有一个 nn 的国际象棋棋盘&#xff08;n 行 n 列的方格图&#xff09;&#xff0c;请在棋盘中摆放 n 个受伤的国际象棋皇后&#xff0c;要求&#xff1a;任何两个皇后不在同一行。任何两个皇后不在同一列。如果两个皇后在同一条 45 度角的…...

CentOS从gcc 4.8.5 升级到gcc 8.3.1

gcc -v查看当前gcc版本。 sudo yum install centos-release-scl-rh安装centos-release-scl-rh。 sudo yum install devtoolset-8-build安装devtoolset-8-build。 显示“Complete!”表示安装成功。 sudo yum install devtoolset-8-gdb安装devtoolset-8-gdb。 显示“Comple…...

【人人都能读标准】12. 原始类型的编码形式

本文为《人人都能读标准》—— ECMAScript篇的第12篇。我在这个仓库中系统地介绍了标准的阅读规则以及使用方式&#xff0c;并深入剖析了标准对JavaScript核心原理的描述。 ECMAScript有7种原始类型&#xff0c;分别是Undefined、Null、Boolean、String、Number、BigInt、Symbo…...

VUE进行前后端交互

目录 一、 跨域 1. 什么是跨域&#xff1f; 2. 什么是本域&#xff1f; 3. 浏览器请求的三种报错 二、SpringBoot解决跨域问题其他前后端跨域请求解决方案 1. SpringBoot上直接添加CrossOrigin 2. 处理跨域请求的Configuration 3. 采用过滤器的方式 3.1 方式一 3.2 方式…...

ThingsBoard Gateway:物联网设备数据采集与集成的强大解决方案

文章目录ThingsBoard Gateway&#xff1a;物联网设备数据采集与集成的强大解决方案1\. ThingsBoard Gateway&#xff1a;概述2\. 主要特点与优势3\. 应用场景4\. 如何使用ThingsBoard Gateway&#xff1a;物联网设备数据采集与集成的强大解决方案 随着物联网&#xff08;IoT&a…...

什么是镜像/raid

镜像&#xff08;Mirroring&#xff09;是一种文件存储形式&#xff0c;是冗余的一种类型&#xff0c;一个磁盘上的数据在另一个磁盘上存在一个完全相同的副本即为镜像。可以把许多文件做成一个镜像文件&#xff0c;与GHOST等程序放在一个盘里用GHOST等软件打开后&#xff0c;又…...

【Python】如何有效比较两个时间序列在图形上的相似度?

文章目录前言一、1.准备二、实操1.使用Matplotlib可视化比较两个时间序列2.计算两个时间序列的相关系数&#xff1a;3.使用Python实现动态时间规整算法&#xff08;DTW&#xff09;&#xff1a;总结前言 比较两个时间序列在图形上是否相似&#xff0c;可以通过以下方法&#x…...

JavaEE-常见的锁策略和synchronized的锁机制

目录常见的锁策略乐观锁和悲观锁轻量级锁和重量级锁自旋锁和挂起等待锁普通互斥锁和读写锁公平锁和非公平锁可重入锁和不可重入锁synchronized的锁机制synchronized特性锁升级/锁膨胀锁消除锁粗化常见的锁策略 乐观锁和悲观锁 乐观锁和悲观锁主要是看主要是锁竞争的激烈程度.…...

信息化,数字化,智能化是三种不同的概念吗?

前两年流行“信息化”&#xff0c;网上铺天盖地都是关于“信息化”的文章&#xff0c;这两年开始流行起“数字化”&#xff0c;于是铺天盖地都是“数字化”的文章。&#xff08;这一点从数字化和信息化这两个关键词热度趋势就可以看出来&#xff09;。 但点开那些文章仔细看看…...

【华为OD机试 2023最新 】 匿名信(C++ 100%)

题目描述 电视剧《分界线》里面有一个片段,男主为了向警察透露案件细节,且不暴露自己,于是将报刊上的字减下来,剪拼成匿名信。 现在又一名举报人,希望借鉴这种手段,使用英文报刊完成举报操作。 但为了增加文章的混淆度,只需满足每个单词中字母数量一致即可,不关注每个…...

硬件语言Verilog HDL牛客刷题day05 时序逻辑部分

1.VL29 信号发生器 1.题目&#xff1a; 题目描述&#xff1a; 请编写一个信号发生器模块&#xff0c;根据波形选择信号wave_choise发出相应的波形&#xff1a;wave_choice0时&#xff0c;发出方波信号&#xff1b;wave_choice1时&#xff0c;发出锯齿波信号&#xff1b;wave…...

Ajax 入门

前端技术&#xff1a;在浏览器中执行的程序都是前端技术。如 html、css、js 等 后端技术&#xff1a;在服务器中执行的长须&#xff0c;使用 Java 等语言开发的后端程序。servlet&#xff0c;jsp&#xff0c;jdbc&#xff0c;mysql&#xff0c;tomacat 等 全局刷新 使用表单…...

半导体器件基础06:发光二极管

说在开头&#xff1a;关于玻尔原子模型&#xff08;1&#xff09; 卢瑟福的模型面临着与经典电磁波理论的矛盾&#xff0c;按照经典电磁波理论&#xff0c;卢瑟福的原子不可能稳定存在超过1秒钟。玻尔面临着选择&#xff1a;要么放弃卢瑟福模型&#xff0c;要么放弃麦克斯韦伟…...

AutoCV第二课:Python基础

目录Python基础前言1.流程控制1.1 条件语句1.2 循环语句1.2.1 while循环语句1.2.2 for循环语句1.3 作业1.4 拓展-try except语法2.函数2.1 函数定义2.2 函数的参数2.2.1 位置参数2.2.2 命名参数2.2.3 默认参数2.2.4 可变参数2.2.5 参数展开2.3 递归函数2.3.1 递归函数定义2.3.2…...

LeetCode算法 打家劫舍 和 打家劫舍II C++

目录题目 打家劫舍参考答案题目 打家劫舍II参考答案题目 打家劫舍 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间相邻的房屋在同一晚上被小偷闯…...

蓝桥杯刷题冲刺 | 倒计时10天

作者&#xff1a;指针不指南吗 专栏&#xff1a;蓝桥杯倒计时冲刺 &#x1f43e;马上就要蓝桥杯了&#xff0c;最后的这几天尤为重要&#xff0c;不可懈怠哦&#x1f43e; 文章目录1.有边数限制的最短路2.九进制转十进制1.有边数限制的最短路 题目 链接&#xff1a; 853. 有边数…...

个人练习-Leetcode-剑指 Offer II 109. 开密码锁

题目链接&#xff1a;https://leetcode.cn/problems/zlDJc7/ 题目大意&#xff1a;给出一个四位数字的密码锁&#xff0c;初始状态是0000&#xff0c;目标是targer。每一次转动只能让一个位的轮盘转动一下&#xff08;0往后转是9&#xff09;。有一个vector<string> dea…...

四个常见的Linux面试问题

四个常见的Linux面试问题。 刚毕业要找工作了&#xff0c;只要是你找工作就会有面试这个环节&#xff0c;那么在面试环节中&#xff0c;有哪些注意事项值得我的关注呢&#xff1f;特别是专业技术岗位&#xff0c;这样的岗位询问一般都是在职的工程师&#xff0c;如何在面试环节…...

15、接口(C#)

15.1 什么是接口 接口是指定一组函数成员而不实现它们的引用类型。所以只能类和结构实现接口。 15.2 声明接口 接口声明不能包含以下成员 数据成员静态成员 接口声明只能包含以下类型的费静态成员函数声明&#xff1a; 方法事件索引器属性 这些函数成员的声明不能包含任何实…...