Vue常用自定义指令、纪录篇

文章目录

    • 一、元素尺寸发生变化时
    • 二、点击元素外自定义指令
    • 三、元素拖拽自定义指令
    • 四、防抖自定义指令
    • 五、节流自定义指令
    • 六、权限判断自定义指令

一、元素尺寸发生变化时

使用场景:
当元素的尺寸发生变化时需要去适配一些元素时。
或者在元素尺寸发生变化时要去适配ECharts
等多种场景,完整代码如下

<!-- Vue3写法 -->
<template><div class="resize"><div class="box" v-resize="onResize"></div></div>
</template><script setup lang="ts">// 监听元素大小变化的指令
const map = new WeakMap()
const ob = new ResizeObserver((entries) => {for (const entry of entries) {// 获取dom元素的回调const handler = map.get(entry.target)//存在回调函数if (handler) {// 将监听的值给回调函数handler({width: entry.borderBoxSize[0].inlineSize,height: entry.borderBoxSize[0].blockSize})}}
})const vResize = {mounted(el: any, binding: any) {//将dom与回调的关系塞入mapmap.set(el, binding.value)//监听el元素的变化ob.observe(el)},unmounted(el: any) {//取消监听ob.unobserve(el)}
}function onResize() {console.log("元素的大小发生了改变")
}
</script><style scoped lang="scss">
.resize {width: 80%;margin: 200px auto 0px;.box {margin-top: 50px;width: 100%;height: 200px;border: 1px solid #000;}
}
</style>

二、点击元素外自定义指令

使用场景:
下拉菜单:当用户点击下拉菜单或模态窗口外部区域时,关闭下拉菜单或模态窗口。
上下文菜单:在右键打开的上下文菜单中,当用户点击菜单外的其他地方时,关闭上下文菜单。
等多种场景,完整代码如下

<template><div class="clickoutside"><div class="button" @click.self="buttonClick" v-clickoutside="buttonClickoutside"> 就当是个按钮<div class="inner" :class="dropdownVisible ? 'dropdownOpen' : ''"></div></div></div>
</template><script setup lang="ts">
import { ref } from 'vue'const vClickoutside = {mounted(el: any, bindings: any) {el.clickOutsideEvent = (event: any) => {// 判断点击是否发生在 el 外部if (!(el === event.target || el.contains(event.target))) {// 如果是,调用绑定的方法bindings.value();}};document.addEventListener('click', el.clickOutsideEvent);},unmounted(el: any) {// 移除事件监听document.removeEventListener('click', el.clickOutsideEvent);},
}
const dropdownVisible = ref(false)function buttonClick() {dropdownVisible.value = !dropdownVisible.value
}function buttonClickoutside() {dropdownVisible.value = falseconsole.log("点击了外面")
}
</script><style scoped lang="scss">
.clickoutside {width: 80%;margin: 200px auto 0px;.button {background: #409EFF;width: 160px;text-align: center;height: 44px;line-height: 44px;border-radius: 4px;color: #fff;cursor: pointer;position: relative;.inner {top: 54px;width: 100%;height: 0px;transition: 0.3s;position: absolute;background: red;}.dropdownOpen {height: 200px;}}
}
</style>

点击按钮时弹出红色区域,再次点击按钮或者按钮外部区域时收起红色区域。
在这里插入图片描述

三、元素拖拽自定义指令

使用场景:
允许用户自由拖拽组件、窗口、等其他元素
各个场景不同,根据自己需求来。
完整代码如下:

<template><div class="drag"><div class="box" v-drag></div></div>
</template><script setup lang="ts">const vDrag = {mounted(el: any) {let active = false; // 拖拽状态let currentX = 0; // 当前鼠标的 X 坐标let currentY = 0; // 当前鼠标的 Y 坐标let initialX = 0; // 初始鼠标按下时相对于元素的 X 偏移量let initialY = 0; // 初始鼠标按下时相对于元素的 Y 偏移量el.addEventListener("mousedown", (e: any) => {// 元素鼠标按下事件// 记录初始鼠标按下时相对于元素的偏移量initialX = e.clientX - el.offsetLeftinitialY = e.clientY - el.offsetTopactive = true; // 设置为正在拖拽状态})document.addEventListener("mouseup", () => {active = false;  // 鼠标抬起,结束拖拽状态})document.addEventListener("mousemove", (e: any) => {// 处于正在拖拽时if (active) {currentX = e.clientX - initialX; // 计算当前鼠标相对于初始的 X 坐标currentY = e.clientY - initialY; // 计算当前鼠标相对于初始的 Y 坐标const x = Math.max(0, Math.min(currentX, window.innerWidth - el.offsetWidth)); // 限制 X 坐标范围const y = Math.max(0, Math.min(currentY, window.innerHeight - el.offsetHeight));// 限制 Y 坐标范围el.style.left = `${x}px`; // 设置元素的 left 位置el.style.top = `${y}px`; // 设置元素的 top 位置}})},
}</script><style scoped lang="scss">
.drag {.box {width: 150px;height: 150px;position: fixed;cursor: pointer;border-radius: 6px;background: #409EFF;}
}
</style>

在这里插入图片描述

四、防抖自定义指令

使用场景:
当用户重复点击按钮时,在1秒再次点击不会触发提交,只有超过一秒并且没有新的点击才会触发提交
输入框输入等可能存在频繁触发的场景
完整代码如下:

<template><div class="debounce"><div class="button" v-debounce-directive="debounceDirective">登 录</div></div>
</template><script setup lang="ts">const vDebounceDirective = {mounted(el: any, binding: any) {// 将元素的事件处理函数替换为防抖后的函数// binding.value 是传入的 debounceDirective 方法el.addEventListener(binding.arg || 'click', debounce(binding.value, 1000));},// 在指令从元素移除时调用unmounted(el: any, binding: any) {el.removeEventListener(binding.arg || 'click', binding.value);},
}function debounceDirective() {console.log("哈哈哈")
}// 防抖函数
const debounce = (fn: Function, delay: number) => {let timer = null as any;return function (...args: any[]) {// 清除之前的定时器if (timer) {clearTimeout(timer);}// 设置新的定时器,延迟后执行函数timer = setTimeout(() => {fn(...args);}, delay);};
};</script><style scoped lang="scss">
.debounce {width: 800px;margin: 200px auto 0px;.button {width: 120px;height: 44px;line-height: 44px;text-align: center;color: #fff;background: #409EFF;border-radius: 4px;cursor: pointer;}
}
</style>

五、节流自定义指令

使用场景
节流有很多种实现发放,通常都是根据不同的应用场景使用不同的方法。

<template><div class="throttle" v-throttle="handleScroll">滚动区域</div>
</template><script setup lang="ts">const handleScroll = () => {// 这里处理滚动相关逻辑console.log('滚动事件触发');
};const vThrottle = {mounted(el: any, binding: any) {// 给元素添加节流处理后的事件监听window.addEventListener('scroll', throttle(binding.value, 5000));},// 指令卸载时unmounted(el: any, binding: any) {window.removeEventListener(binding.arg || 'scroll', binding.value);},
}/*** 节流函数* @param {Function} fn 要执行的函数* @param {number} delay 节流时间间隔(毫秒)* @returns {Function} 节流处理后的函数*/
const throttle = (fn: Function, delay: number) => {let lastCallTime = 0;return function (...args: any[]) {const currentTime = new Date().getTime();if (currentTime - lastCallTime > delay) {fn.apply(this, args);lastCallTime = currentTime;}};
};</script><style scoped lang="scss">
.throttle {height: 30000px;
}
</style>

六、权限判断自定义指令

使用场景:
在后台管理项目中,通常我们会根据用户所拥有的权限去限制该用户有哪些操作按钮
下面来举个例子,对于单个按钮权限的判断和按钮组权限判断
完整代码如下:

单按钮在这里就不用多说什么了。
在这里插入图片描述
在这里插入图片描述
可能会有人不理解按钮组判断了个寂寞。
举个简单的例子,比如说我们用到表格组件,用户A有操作权限则显示表格后面的操作列,用户B没有任何操作时,我们大可没有必要在显示操作列,对就这么简单。
在这里插入图片描述
在这里插入图片描述

<template><div class="hasbtn" v-has-all="'add,edit,delete,see,upload,download'"><div class="btn" v-has="'add'">新增</div><div class="btn" v-has="'edit'">编辑</div><div class="btn" v-has="'delete'">删除</div><div class="btn" v-has="'see'">查看</div><div class="btn" v-has="'upload'">上传</div><div class="btn" v-has="'download'">下载</div></div>
</template><script setup lang="ts">
import { reactive, toRefs, onMounted } from "vue";const state = reactive({userPower: ['add', 'edit'], // 模拟用户所拥有的权限admin: false, // 该用户是否是超级管理员
})
const { } = toRefs(state)onMounted(() => {})// 判断单个按钮权限方法
const hasPermission = (userPermission: any) => {let permissionList = state.userPowerreturn permissionList.some((i: any) => i == userPermission)
};
// 判断单个按钮权限指令
const vHas = {mounted(el: any, binding: any) {if (state.admin) { // 当用户是超级管理时,拥有所有按钮的权限return true} else {if (!hasPermission(binding.value)) {// 如果用户没有某个权限移除改元素el.parentNode.removeChild(el);}}},
}// 判断按钮组权限方法
const hasAllPermission = (userPermission: any) => {let data = userPermission.split(",")return hasOneItemInCommon(data, state.userPower)
}
// 判断按钮组权限指令
const vHasAll = {mounted(el: any, binding: any) {if (state.admin) { // 当用户是超级管理时,拥有所有按钮的权限return true} else {if (!hasAllPermission(binding.value)) {// 如果用户没有某个权限移除改元素el.parentNode.removeChild(el);}}},
}const hasOneItemInCommon = (arr1: any, arr2: any) => {for (const item of arr2) {if (arr1.includes(item)) {return true;}}return false;
};
</script><style scoped lang="scss">
.hasbtn {display: flex;align-items: center;justify-content: center;.btn {width: 120px;height: 44px;line-height: 44px;text-align: center;color: #fff;background: #409EFF;border-radius: 4px;cursor: pointer;margin-right: 20px;}
}
</style>

工作中如遇到新的自定义指令会继续补充。

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

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

相关文章

C# 命名空间和 using 指令详解

在C#编程中&#xff0c;命名空间&#xff08;Namespaces&#xff09;用于组织代码元素&#xff0c;如类、接口、枚举等&#xff0c;以避免命名冲突。using 指令用于导入命名空间&#xff0c;使得代码中可以方便地引用其中的类型&#xff0c;而不必每次都使用完整的命名空间路径…

WPS/Office(Word、Excel、PPT) 自动测评方法

在各高等、中等院校的计算机类课程中,计算机基本应用技能的上机操作考试,广受重视,大为盛行。其中,office(word、excel、ppt)上机考试最为普遍。于是,实现这类Office文档操作的自动阅卷评分,很有必要。本人最近项目上刚好遇到需要解决这种自动评分的问题,所以再次记录下解决的…

TiDB学习9:Ti Cloud简介

目录 1. 为什么选择TiDB 2. 多租户 3. TiDB架构 4. 什么是TiDB Cloud 5. TiDB Cloud Provider Region 6. TiDB Cloud 入门 6.1 在浏览器中打开TiDB Cloud 6.2 创建您的账户 6.3 Developer Tier 与Dedicated Tier 6.3.1 Developer Tier 6.3.2 Dedicated Tier 6.3.2.…

[HUBUCTF 2022 新生赛]RSAaaa

题目&#xff1a; EXP 就你小子是黑客&#xff1f; 我忘记怎么解密了&#xff01; 靠你了&#xff0c;大黑阔&#xff01;(536970330703, 65537) message: 473878130775 40132555282 40132555282 94619939727 72818765591 208015808884 42561234694 159353248388 27748063975 1…

逆天工具一键修复图片,视频去码。简直不要太好用!

今天&#xff0c;我要向您推荐一款功能强大的本地部署软件&#xff0c;它能够在您的计算机上一键修复图片和视频&#xff0c;去除令人不悦的码赛克&#xff08;轻度马赛克&#xff09;。这款软件是开源的&#xff0c;并在GitHub上公开可用&#xff0c;您可以免费下载并使用。 …

Scala 柯里化、sortBy方法

Scala高级特性 小白的Scala学习笔记 2024/5/30 8:42 文章目录 Scala高级特性柯里化sortBy方法 柯里化 参数可以写在两个括号里面 object TestKeli {def add(a:Int)(b:Int)abdef main(args: Array[String]): Unit {val res add(22)(33)println(res)} }可以填隐式参数&#x…

vector的功能讲解与底层实现

本文主要介绍vector的内容以及使用和模拟实现。 vector在英文翻译中是矢量的意思&#xff0c;但在c中他的本质是一个顺序表&#xff08;容器&#xff09;&#xff0c;是一个类模板&#xff0c;&#xff08;用模板创建变量就要参考我们之前的实例化内容了&#xff09;用可以改变…

dnsrecon一键开始负载平衡检测(KALI工具系列十四)

目录 1、KALI LINUX简介 2、lbd工具简介 3、在KALI中使用lbd 3.1 测试目标域名是否存在负载不平衡 4、总结 1、KALI LINUX简介 Kali Linux 是一个功能强大、多才多艺的 Linux 发行版&#xff0c;广泛用于网络安全社区。它具有全面的预安装工具和功能集&#xff0c;使其成为…

杭州服务器的性能如何?

挥洒激情&#xff0c;开启杭州服务器的无限可能&#xff01; 互联网时代&#xff0c;服务器的性能就如同一艘航空母舰&#xff0c;承载着企业的发展梦想&#xff0c;指引着行业的发展方向。而对于杭州服务器&#xff0c;其性能究竟如何&#xff1f;让我来告诉您。 杭州服务器…

撸广告赚金币小游戏app开发

在app上投放广告有哪些注意事项&#xff1f; 在app上投放广告需要注意以下几个方面。 首先&#xff0c;要选择合适的广告形式。根据自己的需求和目标受众&#xff0c;选择合适的广告形式&#xff0c;如横幅广告、插屏广告、视频广告等。不同的广告形式适用于不同的场景和目标…

TCP协议详解及其相关的10个核心机制(面试重点)

TCP协议的报文格式 TCP协议有连接&#xff0c;可靠性传输&#xff0c;面向字节流&#xff0c;全双工。 他的数据格式如图&#xff1a; 根据他的数据格式&#xff0c;在这里我们只知道 16位源端口号&#xff08;表示客户端这里的端口号&#xff09;&#xff0c;16位目的端口号&…

算法简单笔记4

5月31号&#xff0c;明天决赛&#xff0c;今天脑子也是一滩浆糊&#xff0c;踏马的一道题也做不出来&#xff0c;超级难受&#xff0c;只好简单复盘一下两道之前的题目&#xff0c;看完就差不多了&#xff0c;再学也没啥用了&#xff0c;写完这两题题解我就回去打把steam绝地求…

零基础学会asp.net做AI大模型网站/小程序之五:实战初体验(简单网站教学--动态网页制作)

关注我,持续分享逻辑思维&管理思维&面试题; 可提供大厂面试辅导、及定制化求职/在职/管理/架构辅导; 博主在互联网大厂深耕近二十年,从一线码农做起,到人工智能公司副总裁。希望把过往经验总结出来,帮助到更多同学。有兴趣可关注博主后加个人微信(平台规定文章…

深度学习聚类再升级!新算法实现强悍性能,准确率超98%

深度聚类不仅继承了传统聚类算法的优点&#xff0c;在对高维和非线性数据的处理能力&#xff0c;以及自适应性和抗噪性方面也具有很大优势。 具体来说&#xff0c;结合深度学习的聚类算法通过利用深度神经网络的强大特征提取能力&#xff0c;自动学习和识别数据中的复杂结构和…

lru_cache 装饰器的作用

lru_cache 装饰器的主要作用是缓存函数的结果&#xff0c;以减少不必要的计算。在您的代码中&#xff0c;lru_cache(maxsizeNone) 装饰器被用于 load_model 函数。这意味着当 load_model 函数被多次调用&#xff0c;且参数 model_path 相同时&#xff0c;函数的结果会被缓存&am…

全志H616(BIGTREETECH CB1)和 博通BCM2711(树莓派4B)CPU对比测试

一&#xff0c;实物对比图&#xff1a; BIGTREETECH CB1的底板接口的分布和树莓派4B是一样的&#xff0c;但是没有树莓派的音频接口&#xff0c;底板也不能放到树莓派4B的官方外壳里&#xff0c;因为底板的背面有一个DSI接口&#xff0c;高度超出了。 二&#xff0c;开发板硬…

HBSL-22Q/K定时限过电流继电器 板前接线 JOSEF约瑟

HBSL系列静态定时限过电流继电器 系列型号&#xff1a; HBSL-11A/E静态定时限过电流继电器&#xff1b;HBSL-11A/K静态定时限过电流继电器&#xff1b;HBSL-12A/E静态定时限过电流继电器&#xff1b; HBSL-12A/K静态定时限过电流继电器&#xff1b;HBSL-21A/E静态定时限过电…

JS-09-es6常用知识1

目录 1 模板字符串 1.1 模板字符串基本用法 1.2 模板字符串解决了一些痛点 2 解构赋值 2.1 对象的解构赋值 2.2 函数参数的解构赋值 2.3 补写&#xff1a;属性的简写 3 rest参数 3.1 arguments 3.2 rest参数 3.3 补充&#xff1a;判断数据类型 4 箭头函数 4.1 …

SpringBoot-世界杯足球赛网站-28567

Springboot世界杯足球赛网站 摘 要 信息化社会内需要与之针对性的信息获取途径&#xff0c;但是途径的扩展基本上为人们所努力的方向&#xff0c;由于站在的角度存在偏差&#xff0c;人们经常能够获得不同类型信息&#xff0c;这也是技术最为难以攻克的课题。针对世界杯足球赛…

jsmug:一个针对JSON Smuggling技术的测试PoC环境

关于jsmug jsmug是一个代码简单但功能强大的JSON Smuggling技术环境PoC&#xff0c;该工具可以帮助广大研究人员深入学习和理解JSON Smuggling技术&#xff0c;并辅助提升Web应用程序的安全性。 背景内容 JSON Smuggling技术可以利用目标JSON文档中一些“不重要”的字节数据实…