你vue有写过自定义指令吗?知道自定义指令的应用场景有哪些吗?

一、什么是指令

开始之前我们先学习一下指令系统这个词

指令系统是计算机硬件的语言系统,也叫机器语言,它是系统程序员看到的计算机的主要属性。因此指令系统表征了计算机的基本功能决定了机器所要求的能力

vue中提供了一套为数据驱动视图更为方便的操作,这些操作被称为指令系统

我们看到的v-开头的行内属性,都是指令,不同的指令可以完成或实现不同的功能

除了核心功能默认内置的指令 (v-model 和 v-show),Vue 也允许注册自定义指令

指令使用的几种方式:

//会实例化一个指令,但这个指令没有参数 
`v-xxx`// -- 将值传到指令中
`v-xxx="value"`  // -- 将字符串传入到指令中,如`v-html="'<p>内容</p>'"`
`v-xxx="'string'"` // -- 传参数(`arg`),如`v-bind:class="className"`
`v-xxx:arg="value"` // -- 使用修饰符(`modifier`)
`v-xxx:arg.modifier="value"` 

二、如何实现

注册一个自定义指令有全局注册与局部注册

全局注册主要是通过Vue.directive方法进行注册

Vue.directive第一个参数是指令的名字(不需要写上v-前缀),第二个参数可以是对象数据,也可以是一个指令函数

// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {// 当被绑定的元素插入到 DOM 中时……inserted: function (el) {// 聚焦元素el.focus()  // 页面加载完成之后自动让输入框获取到焦点的小功能}
})

局部注册通过在组件options选项中设置directive属性

directives: {focus: {// 指令的定义inserted: function (el) {el.focus() // 页面加载完成之后自动让输入框获取到焦点的小功能}}
}

然后你可以在模板中任何元素上使用新的 v-focus property,如下:

<input v-focus />

自定义指令也像组件那样存在钩子函数:

  • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置

  • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)

  • update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新

  • componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用

  • unbind:只调用一次,指令与元素解绑时调用

所有的钩子函数的参数都有以下:

  • 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 }
  • vnodeVue 编译生成的虚拟节点
  • oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用

除了 el 之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的 dataset 来进行

举个例子:

<div v-demo="{ color: 'white', text: 'hello!' }"></div>
<script>Vue.directive('demo', function (el, binding) {console.log(binding.value.color) // "white"console.log(binding.value.text)  // "hello!"})
</script>

三、应用场景

使用自定义指令可以满足我们日常一些场景,这里给出几个自定义指令的案例:

  • 表单防止重复提交
  • 图片懒加载
  • 一键 Copy的功能

表单防止重复提交

表单防止重复提交这种情况设置一个v-throttle自定义指令来实现

举个例子:

// 1.设置v-throttle自定义指令
Vue.directive('throttle', {bind: (el, binding) => {let throttleTime = binding.value; // 节流时间if (!throttleTime) { // 用户若不设置节流时间,则默认2sthrottleTime = 2000;}let cbFun;el.addEventListener('click', event => {if (!cbFun) { // 第一次执行cbFun = setTimeout(() => {cbFun = null;}, throttleTime);} else {event && event.stopImmediatePropagation();}}, true);},
});
// 2.为button标签设置v-throttle自定义指令
<button @click="sayHello" v-throttle>提交</button>

图片懒加载

设置一个v-lazy自定义指令完成图片懒加载

const LazyLoad = {// install方法install(Vue,options){// 代替图片的loading图let defaultSrc = options.default;Vue.directive('lazy',{bind(el,binding){LazyLoad.init(el,binding.value,defaultSrc);},inserted(el){// 兼容处理if('IntersectionObserver' in window){LazyLoad.observe(el);}else{LazyLoad.listenerScroll(el);}},})},// 初始化init(el,val,def){// data-src 储存真实srcel.setAttribute('data-src',val);// 设置src为loading图el.setAttribute('src',def);},// 利用IntersectionObserver监听elobserve(el){let io = new IntersectionObserver(entries => {let realSrc = el.dataset.src;if(entries[0].isIntersecting){if(realSrc){el.src = realSrc;el.removeAttribute('data-src');}}});io.observe(el);},// 监听scroll事件listenerScroll(el){let handler = LazyLoad.throttle(LazyLoad.load,300);LazyLoad.load(el);window.addEventListener('scroll',() => {handler(el);});},// 加载真实图片load(el){let windowHeight = document.documentElement.clientHeightlet elTop = el.getBoundingClientRect().top;let elBtm = el.getBoundingClientRect().bottom;let realSrc = el.dataset.src;if(elTop - windowHeight<0&&elBtm > 0){if(realSrc){el.src = realSrc;el.removeAttribute('data-src');}}},// 节流throttle(fn,delay){let timer; let prevTime;return function(...args){let currTime = Date.now();let context = this;if(!prevTime) prevTime = currTime;clearTimeout(timer);if(currTime - prevTime > delay){prevTime = currTime;fn.apply(context,args);clearTimeout(timer);return;}timer = setTimeout(function(){prevTime = Date.now();timer = null;fn.apply(context,args);},delay);}}}
export default LazyLoad;

一键 Copy的功能

关于自定义指令还有很多应用场景,如:拖拽指令、页面水印、权限校验等等应用场景

参考文献

  • https://vue3js.cn/docs/zh
  • https://juejin.cn/post/6844904197448531975#heading-5
  • https://www.cnblogs.com/chenwenhao/p/11924161.html#_label2

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/595152.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL的基础架构之内部执行过程

MySQL的逻辑架构图 如上图所示&#xff0c;MySQL可以分为Server层和存储引擎层两部分&#xff1a; 1&#xff09;Server层涵盖了MySQL的大多数核心服务功能&#xff0c;以及所有的内置函数&#xff08;如日期、时间、数学和加密函数等&#xff09;&#xff0c;所有跨存储引擎…

linux新M2固态挂载

一、普通挂载 查看硬盘信息 sudo fdisk -l创建文件系统 sudo mkfs.ext4 /dev/nvme0n1创建挂载点 sudo mkdir /home/zain挂载 sudo mount /dev/nvme0n1 /home/zain二、永久挂载 vi /etc/fstabinsert&#xff1a; /dev/nvme0n1 /home/zain ext4 defaults 0 2 wqs…

知识笔记(六十九)———缓冲区溢出攻击

1. 什么是缓冲区溢出 &#xff08;1&#xff09;缓冲区 缓冲区是一块连续的计算机内存区域&#xff0c;用于在将数据从一个位置移到另一位置时临时存储数据。这些缓冲区通常位于 RAM 内存中&#xff0c;可保存相同数据类型的多个实例&#xff0c;如字符数组。 计算机经常使用…

3.10 Android eBPF HelloWorld调试(四)

一,读取eBPF map的android应用程序示例 1.1 C++源码及源码解读 /system/memory/bpfmapparsed/hello_world_map_parser.cpp //基于aosp android12#define LOG_TAG "BPF_MAP_PARSER"#include <log/log.h> #include <stdlib.h> #include <unistd.h&g…

Day22 112路径总和 113路径总和II 106中后构造二叉树/中前构造二叉树 654最大二叉树

给定一个二叉树和一个目标和&#xff0c;判断该树中是否存在根节点到叶子节点的路径&#xff0c;这条路径上所有节点值相加等于目标和。 递归&#xff1a; 可以采用深度优先的递归方式&#xff0c;前中后序都可以&#xff08;因为中节点没有处理逻辑&#xff09;。首先确定参…

放大镜Scratch-第14届蓝桥杯Scratch省赛真题第3题

3. 放大镜&#xff08;50分&#xff09; 评判标准&#xff1a; 10分&#xff1a;满足"具体要求"中的1&#xff09;&#xff1b; 15分&#xff1a;满足"具体要求"中的2&#xff09;&#xff1b; 25分&#xff0c;满足"具体要求"中的3&#xff…

C#高级:Lambda表达式分组处理2(WITH ROLLUP关键字)

目录 一、问题引入 二、with rollup查询 三、去掉多余数据 四、拓展 一、问题引入 查询SQL后结果如下&#xff0c;字段分别是用户、项目、批次、工作时间&#xff1a; SELECT UserID,ProjectID,ProBatchesID,WorkHour FROM MAINTABLE GROUP BY HourFiller ,ProjectID ,…

【ESP32接入国产大模型之文心一言】

1. 怎样接入文心一言 随着人工智能技术的不断发展&#xff0c;自然语言处理领域也得到了广泛的关注和应用。在这个领域中&#xff0c;文心一言作为一款强大的自然语言处理工具&#xff0c;具有许多重要的应用价值。本文将重点介绍如何通过ESP32接入国产大模型之文心一言api&am…

图片中src属性绑定不同的路径

vue3 需求是按钮disable的时候&#xff0c;显示灰色的icon&#xff1b;非disable状态&#xff0c;显示白色的icon 一开始src写成三元表达式&#xff0c;发现不行&#xff0c;网上说src不能写成三元表达式&#xff0c;vue会识别成字符串 最后的解决方案 同时&#xff0c;发现…

软件测试基础理论学习-软件测试概论(流程,bug,测试用例)

测试的流程 也可以理解为测试工程师在软件开发中需要介入的部分&#xff0c;个人总结如下&#xff1a; 需求分析。这个部分主要就是针对需求提出一些不合理的地方&#xff0c;也可以让测试人员对整个软件模型和需求进行整体的掌握和把控&#xff0c;如果出现了不合理的地方&am…

2401d,d随机选择类

原文 我有一个许多类实现的接口,我想随机选择其中一个实现.还有两个约束:首先,不是均匀分布,所有类都可定义被选中的机会(反映在"weight()"函数中).而且根据运行时信息,并非所有类都可用. 我搞了个最小工作示例,但它很重(特别是因为有中间枚举),可更漂亮,更易于理解…

在Cadence中单独添加或删除器件与修改网络的方法

首先需要在设置中使能 ,添加或修改逻辑选项。 添加或删除器件&#xff0c;点击logic-part&#xff0c;选择需要添加或删除的器件&#xff0c;这里的器件必须是PCB中已经有的器件&#xff0c;Refdes中输入添加或删除的器件标号&#xff0c;点击Add添加。 添加完成后就会显示在R1…

基于springboot智慧食堂管理系统源码和论文

随着Internet的发展&#xff0c;人们的日常生活已经离不开网络。未来人们的生活与工作将变得越来越数字化&#xff0c;网络化和电子化。网上管理&#xff0c;它将是直接管理“智慧食堂”系统的最新形式。本论文是以构建“智慧食堂”系统为目标&#xff0c;使用java技术制作&…

MATLAB中dlmread函数用法

目录 语法 说明 示例 读取整个带分隔符的文件 读取包含空的分隔字段的文件 从特定行和列偏移量开始读取带分隔符的文件 读取带分隔符的文件中的特定范围 dlmread函数的功能是将 ASCII 分隔的数值数据文件读取到矩阵。 语法 M dlmread(filename) M dlmread(filename,…

uView Calendar 日历

此组件用于单个选择日期&#xff0c;范围选择日期等&#xff0c;日历被包裹在底部弹起的容器中。 注意&#xff1a; 此组件与Picker 选择器的日期选择模式有一定的重合之处&#xff0c;区别在于本组件为更专业的日期选择场景&#xff0c;能选择日期范围等。 另外Picker组件的日…

Clickhouse SQL字符串相关

1、列表 列转行 列转行就是将某一没有重复数据的列进行转换之后变成可以与其他数据对应起来的有重复数据的列 列转行&#xff0c;将一个字段中的多值按某分隔符进行炸开&#xff0c;分为多行 arrayJoin(splitByString(&#xff0c;, cast(data_detail as String))) AS col行转…

odoo17 | 基本视图

前言 我们在上一章中已经看到Odoo能够为给定模型生成默认视图。在实践中&#xff0c;默认视图是绝对不可接受的用于商业应用程序。相反&#xff0c;我们至少应该以逻辑方式组织各种字段。 视图在带有动作和菜单的XML文件中定义。它们是ir.ui.view模型的实例。 在我们的房地产…

OpenHarmony从入门到放弃(一)

OpenHarmony从入门到放弃&#xff08;二&#xff09; 一、OpenHarmony的基本概念和特性 OpenHarmony是由开放原子开源基金会孵化及运营的开源项目&#xff0c;其目标是构建一个面向全场景、全连接、全智能的时代的智能终端设备操作系统。 分布式架构 OpenHarmony采用分布式…

Termius for Mac/Win:一款功能强大的终端模拟器、SSH 和 SFTP 客户端软件

随着远程工作和云技术的普及&#xff0c;对于高效安全的远程访问和管理服务器变得至关重要。Termius&#xff0c;一款强大且易用的终端模拟器、SSH 和 SFTP 客户端软件&#xff0c;正是满足这一需求的理想选择。 Termius 提供了一站式的解决方案&#xff0c;允许用户通过单一平…

什么是Alibaba Cloud Linux?完全兼容CentOS,详细介绍

Alibaba Cloud Linux是基于龙蜥社区OpenAnolis龙蜥操作系统Anolis OS的阿里云发行版&#xff0c;针对阿里云服务器ECS做了大量深度优化&#xff0c;Alibaba Cloud Linux由阿里云官方免费提供长期支持和维护LTS&#xff0c;Alibaba Cloud Linux完全兼容CentOS/RHEL生态和操作方式…