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

【Vue3】自定义指令

除了 Vue 内置的一系列指令 (比如 v-modelv-show) 之外,Vue 还允许你注册自定义的指令 (Custom Directives)。

1. 生命周期钩子函数

一个自定义指令由一个包含类似组件生命周期钩子的对象来定义。钩子函数会接收到指令所绑定元素作为其参数。

<script setup> 中,任何以 v 开头的驼峰式命名的变量都可以被用作一个自定义指令。

<!-- App.vue -->
<template><div><button>切换</button><!-- 钩子函数里面都可以接受这些值myParam: 自定义参数;myModifier: 自定义修饰符 --><A v-move:myParam.myModifier="{ background: 'pink' }"></A></div>
</template><script setup lang="ts">
import { reactive, ref, Directive } from 'vue';
import A from './components/A.vue';
import B from './components/B.vue';
let flag = ref<boolean>(true)
const vMove: Directive = {created() {console.log('created')},beforeMount() {console.log('beforeMount')},mounted(...args: Array<any>) {console.log('mounted')console.log(args);},beforeUpdate() {console.log('beforeUpdate')},updated() {console.log('updated')},beforeUnmount() {console.log('beforeUnmount')},unmounted() {console.log('unmounted')}
}
</script><style scoped lang="less"></style>

在这里插入图片描述

  • 0:该 div 元素。
  • 1:传入的参数等。比如 arg 参数,modifiers 自定义修饰符,dir 目录,传入的 value 值,instance 组件实例。
  • 2:当前组件的虚拟 DOM
  • 3:上一个虚拟 DOM
<!-- App.vue -->
<template><div><button>切换</button><!-- 钩子函数里面都可以接受这些值myParam: 自定义参数;myModifier: 自定义修饰符 --><A v-move:myParam.myModifier="{ background: 'pink' }"></A></div>
</template><script setup lang="ts">
import { reactive, ref, Directive, DirectiveBinding } from 'vue';
import A from './components/A.vue';
import B from './components/B.vue';
let flag = ref<boolean>(true)
type Dir = {background: string;
}
const vMove: Directive = {created() {console.log('created')},beforeMount() {console.log('beforeMount')},mounted(el: HTMLElement, dir: DirectiveBinding<Dir>) {console.log('mounted')console.log(el);console.log(dir);el.style.background = dir.value.background;},// 传入的数据发生变化(比如此时的background)时触发 beforeUpdate 和 updatedbeforeUpdate() {console.log('beforeUpdate')},updated() {console.log('updated')},beforeUnmount() {console.log('beforeUnmount')},unmounted() {console.log('unmounted')}
}
</script><style scoped lang="less"></style>

在这里插入图片描述

2. 指令简写

<!-- App.vue -->
<template><div class="btns"><button v-has-show="123">创建</button><button>编辑</button><button>删除</button></div>
</template><script setup lang="ts">
import { reactive, ref, DirectiveBinding } from 'vue';
import type { Directive } from 'vue'
const vHasShow: Directive = (el, binding) => {console.log(el, binding) ;
}
</script><style scoped lang="less">
.btns {button {margin: 10px;}
}
</style>

在这里插入图片描述

应用场景1:按钮鉴权

根据能否从 localStorage(或者后台返回) 中获取数据,来判断是否显示某个按钮。

<!-- App.vue -->
<template><div class="btns"><button v-has-show="'shop:create'">创建</button><button v-has-show="'shop:edit'">编辑</button><button v-has-show="'shop:delete'">删除</button></div>
</template><script setup lang="ts">
import { reactive, ref, DirectiveBinding } from 'vue';
import type { Directive } from 'vue'
localStorage.setItem('userId', 'xiuxiu')
// mock 后台返回的数据
const permissions = ['xiuxiu:shop:create',// 'xiuxiu:shop:edit',  // 后台没有相应数据,则不显示该对应的按钮'xiuxiu:shop:delete'
]
const userId = localStorage.getItem('userId') as string
const vHasShow: Directive = (el, binding) => {if(!permissions.includes(userId + ':' + binding.value)) {el.style.display = 'none'}
}
</script><style scoped lang="less">
.btns {button {margin: 10px;}
}
</style>

在这里插入图片描述

应用场景2:鼠标拖拽

拖拽粉色框移动大盒子。

<!-- App.vue -->
<template><div v-move class="box"><div class="header"></div><div>内容</div></div>
</template><script setup lang="ts">
import { Directive, DirectiveBinding } from 'vue';const vMove:Directive<any,void> = (el:HTMLElement, binding:DirectiveBinding)=> {let moveElement:HTMLElement = el.firstElementChild as HTMLElement;console.log(moveElement);const mouseDown = (e:MouseEvent) => {// 记录原始位置// clientX 鼠标点击位置的X轴坐标// clientY 鼠标点击位置的Y轴坐标// offsetLeft 鼠标点击的子元素距离其父元素的左边的距离// offsetTop 鼠标点击的子元素距离其父元素的顶部的距离let X = e.clientX - el.offsetLeft;let Y = e.clientY - el.offsetTop;const move = (e:MouseEvent) => {console.log(e);el.style.left = e.clientX - X + 'px';el.style.top = e.clientY - Y + 'px';}document.addEventListener('mousemove', move);document.addEventListener('mouseup', () => {document.removeEventListener('mousemove', move);})}moveElement.addEventListener('mousedown', mouseDown);
}
</script><style scoped lang="less">
.box {position: fixed;height: 200px;width: 200px;top: 50%;left: 50%;transform: translate(-50%, -50%);border: 1px solid #000;.header {height: 50px;width: 100%;background: pink;border-bottom: #000 1px solid;}
}
</style>

在这里插入图片描述

应用场景3:懒加载

let imageList = import.meta.glob('./assets/images/*.*', { eager: true })

在这里插入图片描述

let imageList = import.meta.glob('./assets/images/*.*')

在这里插入图片描述

 // 判断图片是否在可视区const observer = new IntersectionObserver((e)=> {console.log(e[0]);})  // 监听元素observer.observe(el)

在这里插入图片描述
在这里插入图片描述

<!-- App.vue -->
<template><div><div><img v-lazy="item" width="400" height="500" v-for="item in arr" alt=""></div></div>
</template><script setup lang="ts">
import { Directive, DirectiveBinding } from 'vue';let imageList:Record<string,{default:string}> = import.meta.glob('./assets/images/*.*', { eager: true })
let arr = Object.values(imageList).map(item=>item.default)
console.log(arr);
let vLazy:Directive<HTMLImageElement,string> = async (el,binding)=> {const def = await import('./assets/pinia.svg')el.src = def.default// 判断图片是否在可视区const observer = new IntersectionObserver((e)=> {console.log(e[0],binding.value);if(e[0].intersectionRatio > 0) {setTimeout(()=> {el.src = binding.value},2000)observer.unobserve(el)}})  // 监听元素observer.observe(el)
}
</script><style scoped lang="less"></style>
  1. 进入可视区比例 > 0:

    在这里插入图片描述

  2. 过 2s ,替换图片

    在这里插入图片描述

相关文章:

【Vue3】自定义指令

除了 Vue 内置的一系列指令 (比如 v-model 或 v-show) 之外&#xff0c;Vue 还允许你注册自定义的指令 (Custom Directives)。 1. 生命周期钩子函数 一个自定义指令由一个包含类似组件生命周期钩子的对象来定义。钩子函数会接收到指令所绑定元素作为其参数。 在 <script …...

UG\NX CAM二次开发 加工模块获取 UF _ask_application_module

文章作者:代工 来源网站:NX CAM二次开发专栏 简介: UG\NX CAM二次开发 加工模块获取 UF _ask_application_module 代码: void MyClass::do_it() { // TODO: add your code here // 获取NX当前所在的模块 int module_id = 0; // UF_ask_application_module(&…...

借助GPU算力编译Android

借助GPU算力编译Android 借助GPU编译Android代码的意义在于提高编译的效率和速度。传统的CPU编译方式在处理大量代码时可能会遇到性能瓶颈,而GPU编译利用了显卡的并行计算能力,可以同时处理多个任务,加快编译过程。通过利用GPU的并行计算能力,可以将编译过程中的多个任务分…...

docker-compose一键部署mysql

1.创建安装目录 mnt为硬盘挂载目录&#xff0c;根据实际情况修改 mkdir -p /mnt/mysql cd /mnt/mysql vim docker-compose.yml2.编写docker-compose.yml version: 3.1 services:db:image: mysql:5.7 #mysql版本volumes:- ./data/db:/var/lib/mysql #数据文件- ./etc/my.cnf:/…...

MATLAB 函数签名器

文章目录 MATLAB 函数签名器注释规范模板参数类型 kind数据格式 type选项的支持 使用可执行程序封装为m函数程序输出 编译待办事项推荐阅读附录 MATLAB 函数签名器 MATLAB 函数签名器 (FUNCSIGN) &#xff0c;在规范注释格式的基础上为函数文件或类文件自动生成函数签名&#…...

2019强网杯随便注bugktu sql注入

一.2019强网杯随便注入 过滤了一些函数&#xff0c;联合查询&#xff0c;报错&#xff0c;布尔&#xff0c;时间等都不能用了&#xff0c;尝试堆叠注入 1.通过判断是单引号闭合 ?inject1-- 2.尝试堆叠查询数据库 ?inject1;show databases;-- 3.查询数据表 ?inject1;show …...

Html+Css+Js计算时间差,返回相差的天/时/分/秒(从未来的一个日期时间到当前日期时间的差)。

Html部分 <!DOCTYPE html> <html><head><meta charset"utf-8" /><title></title><link rel"stylesheet" type"text/css" href"css/index.css" /><script src"js/index.js" t…...

mybatis项目启动报错:reader entry: ���� = v

问题再现 解决方案一 由于指定的VFS没有找&#xff0c;mybatis启用了默认的DefaultVFS&#xff0c;然后由于DefaultVFS的内部逻辑&#xff0c;从而导致了reader entry乱码。 去掉mybatis配置文件中关于别名的配置&#xff0c;然后在mapper.xml文件中使用完整的类名。 待删除的…...

【GIT版本控制】--什么是版本控制

一、为什么需要版本控制&#xff1f; 版本控制是在软件开发和许多其他领域中非常重要的工具&#xff0c;因为它解决了许多与协作、追踪更改和管理项目相关的问题。以下是一些主要原因&#xff0c;解释了为什么需要版本控制&#xff1a; 追踪更改历史: 版本控制系统允许您准确…...

ChatGPT付费创作系统V2.3.4独立版 +WEB端+ H5端 + 小程序最新前端

人类小徐提供的GPT付费体验系统最新版系统是一款基于ThinkPHP框架开发的AI问答小程序&#xff0c;是基于国外很火的ChatGPT进行开发的Ai智能问答小程序。当前全民热议ChatGPT&#xff0c;流量超级大&#xff0c;引流不要太简单&#xff01;一键下单即可拥有自己的GPT&#xff0…...

GEE16: 区域日均降水量计算

Precipitation 1. 区域日均降水量计算2. 降水时间序列3. 降水数据年度时间序列对比分析 1. 区域日均降水量计算 今天分析一个计算区域日均降水量的方法&#xff1a; 数据信息&#xff1a;   Climate Hazards Group InfraRed Precipitation with Station data (CHIRPS) is a…...

打开MySQL数据库

在命令行里输入mysql --version就可以查看&#xff1a; mysql -uroot -p之前设置的密码&#xff08;不用输入&#xff09;就可登录成功&#xff1a;...

玩转ChatGPT:DALL·E 3生成图像

一、写在前面 好久不更新咯&#xff0c;因为没有什么有意思的东西分享的。 今天更新&#xff0c;是因为GPT整合了自家的图像生成工具&#xff0c;名字叫作DALLE 3。 DALLE 3是OpenAI推出的一种生成图像的模型&#xff0c;它基于GPT-3架构进行训练&#xff0c;但是它的主要目…...

小程序入门笔记(一) 黑马程序员前端微信小程序开发教程

微信小程序基本介绍 小程序和普通网页有以下几点区别&#xff1a; 运行环境&#xff1a;小程序可以在手机的操作系统上直接运行&#xff0c;如微信、支付宝等&#xff1b;而普通网页需要在浏览器中打开才能运行。 开发技术&#xff1a;小程序采用前端技术进行开发&#xff0c;…...

【进程管理】初识进程

一.何为进程 教材一般会给出这样的答案: 运行起来的程序 或者 内存中的程序 这样说太抽象了&#xff0c;那我问程序和进程有什么区别呢&#xff1f;诶&#xff1f;这我知道&#xff0c;书上说&#xff0c;动态的叫进程&#xff0c;静态的叫程序。那么静态和动态又是什么意思…...

ArcGIS Maps SDK for JS:监听按钮点击事件控制图层的visible属性

文章目录 1 需求描述2 解决方案 1 需求描述 现在有这么一个需求&#xff1a;在地图中添加一些图层&#xff0c;添加图层列表按钮。打开图层列表后用户会打开某些图层使其可见&#xff0c;要求关闭图层列表时&#xff0c;隐藏某些图层&#xff08;若visibletrue&#xff09; 2…...

微信小程序-1

微信开发文档 https://developers.weixin.qq.com/miniprogram/dev/framework/ 报错在调试器的console里找 一、结构 Ctrl 放大字体 Ctrl - 缩小 设置 - - - 外观设置 - - - 可以修改喜欢的主题颜色 index.js index.json index.wxml 》 html <view class"box&qu…...

不容易解的题10.5

31.下一个排列 31. 下一个排列 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/next-permutation/?envTypelist&envIdZCa7r67M会做就不算难题&#xff0c;如果没做过不知道思路&#xff0c;这道题将会变得很难。 这道题相当于模拟cpp的next_permu…...

后端面经学习自测(二)

文章目录 1、Http1.1和2.0的区别大概是什么&#xff1f;HTTP & HTTPS 2、HTTP&#xff0c;用户后续的操作&#xff0c;服务端如何知道属于同一个用户cookie & session & token手机验证码登录流程SSO单点登录 3、如果服务端是一个集群机器&#xff1f;4、hashmap是线…...

使用Jest测试Cesium源码

使用Jest测试Cesium源码 介绍环境Cesium安装Jest安装Jest模块包安装babel安装Jest的VSC插件 测试例子小结 介绍 在使用Cesium时&#xff0c;我们常常需要编写自己的业务代码&#xff0c;其中需要引用Cesium的源码&#xff0c;这样方便调试。此外&#xff0c;目前代码中直接使用…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动&#xff08;如演唱会、马拉松赛事、高考中考等&#xff09;期间&#xff0c;城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例&#xff0c;暖城商圈曾因观众集中离场导致周边…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

基于matlab策略迭代和值迭代法的动态规划

经典的基于策略迭代和值迭代法的动态规划matlab代码&#xff0c;实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅

目录 前言 操作系统与驱动程序 是什么&#xff0c;为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中&#xff0c;我们在使用电子设备时&#xff0c;我们所输入执行的每一条指令最终大多都会作用到硬件上&#xff0c;比如下载一款软件最终会下载到硬盘上&am…...

JS红宝书笔记 - 3.3 变量

要定义变量&#xff0c;可以使用var操作符&#xff0c;后跟变量名 ES实现变量初始化&#xff0c;因此可以同时定义变量并设置它的值 使用var操作符定义的变量会成为包含它的函数的局部变量。 在函数内定义变量时省略var操作符&#xff0c;可以创建一个全局变量 如果需要定义…...

2025年低延迟业务DDoS防护全攻略:高可用架构与实战方案

一、延迟敏感行业面临的DDoS攻击新挑战 2025年&#xff0c;金融交易、实时竞技游戏、工业物联网等低延迟业务成为DDoS攻击的首要目标。攻击呈现三大特征&#xff1a; AI驱动的自适应攻击&#xff1a;攻击流量模拟真实用户行为&#xff0c;差异率低至0.5%&#xff0c;传统规则引…...