19 vue3之自定义指令Directive按钮鉴权

directive-自定义指令(属于破坏性更新)

Vue中有v-if,v-for,v-bind,v-show,v-model 等等一系列方便快捷的指令 今天一起来了解一下vue里提供的自定义指令

Vue3指令的钩子函数

  • created 元素初始化的时候
  • beforeMount 指令绑定到元素后调用 只调用一次
  • mounted 元素插入父级dom调用
  • beforeUpdate 元素被更新之前调用
  • update 这个周期方法被移除 改用updated
  • beforeUnmount 在元素被移除前调用
  • unmounted 指令被移除后调用 只调用一次

Vue2 指令的钩子函数

 bind inserted update componentUpdated unbind

在setup内定义局部指令

但这里有一个需要注意的限制:必须以 vNameOfDirective 的形式来命名本地自定义指令,以使得它们可以直接在模板中使用。

 父组件

<template>
<Av-move-directive.aa.cookie="{background: 'red',}"></A
</template><script setup lang="ts">
import {ref,reactive,Directive,DirectiveBinding,
} from "vue";
import A from "./components/twenty_one_A.vue";
let flag = ref<boolean>(true);
let color = ref<string>("");type Value = {//这样才会提示background,帮助我们做内型推导background: string;
};const vMoveDirective: Directive = {// 自定义指令必须以v开头 Directivecreated: () => {console.log("created初始化====>");},beforeMount(...args: Array<any>) {console.log("beforeMount初始化一次=======>");console.log("args==>", args); // 共有4个参数 1是组件的元素 2是dir 3.是虚拟Dom 4.是上一次更新的dom//获取到这些内容后在元素上做些操作},mounted(el: any, dir: DirectiveBinding<Value>) {el.style.background = dir.value.background;console.log("mounted初始化========>");},beforeUpdate() {console.log("beforeUpdate更新之前");},updated() {console.log("updated更新结束");},beforeUnmount(...args: Array<any>) {console.log(args);console.log("======>beforeUnmount卸载之前");},unmounted(...args: Array<any>) {console.log(args);console.log("======>unmounted卸载完成");},
};</script>

A组件

<template><div class="box">子组件</div>
</template><script setup lang="ts">
import { ref, reactive } from "vue";
</script><style lang="less" scoped>
.box {width: 100px;height: 100px;background: pink;
}
</style>

生命周期钩子参数详解

第一个 el  当前绑定的DOM 元素

第二个 binding

instance:使用指令的组件实例。
value:传递给指令的值。例如,在 v-my-directive="1 + 1" 中,该值为 2。
oldValue:先前的值,仅在 beforeUpdate 和 updated 中可用。无论值是否有更改都可用。
arg:传递给指令的参数(如果有的话)。例如在 v-my-directive:foo 中,arg 为 "foo"。
modifiers:包含修饰符(如果有的话) 的对象。例如在 v-my-directive.foo.bar 中,修饰符对象为 {foo: true,bar: true}。
dir:一个对象,在注册指令时作为参数传递。例如,在以下指令中


第三个 当前元素的虚拟DOM 也就是Vnode

第四个 prevNode 上一个虚拟节点,仅在 beforeUpdate 和 updated 钩子中可用

更新和卸载

 <!-- 卸载 --><!--  <Av-if="flag"v-move-directive="{ background: 'red' }"></A> --><!-- 更新 aa.cookie是随意写的自定义修饰符 --><!-- <Av-move-directive.aa.cookie="{background: 'red',flag: flag,}"></A> -->

函数简写

你可能想在 mounted 和 updated 时触发相同行为,而不关心其他的钩子函数。那么你可以通过将这个函数模式实现

<template><div><input v-model="value" type="text" /><A v-move="{ background: value }"></A></div>
</template><script setup lang='ts'>
import A from './components/A.vue'
import { ref, Directive, DirectiveBinding } from 'vue'
let value = ref<string>('')
type Dir = {background: string
}
const vMove: Directive = (el, binding: DirectiveBinding<Dir>) => {el.style.background = binding.value.background
}
</script><style>
</style>

 自定义指令-按钮鉴权案例

根据权限显示和隐藏对应的按钮

<template><h3>按钮鉴权案例</h3><div><button v-has-button="'shop:create'">新增</button><button v-has-button="'shop:edit'">编辑</button><button v-has-button="'shop:delete'">删除</button></div>
</template><script setup lang="ts">
import {ref,reactive,Directive,DirectiveBinding,
} from "vue";// 按钮鉴权localStorage.setItem("userId", "cookie1");//mock后台返回的数据
const permission = ["cookie1:shop:edit","cookie1:shop:create",// "cookie1:shop:delete",
];
const userId = localStorage.getItem("userId") as string;
const vHasButton: Directive<HTMLElement, string> = (el,bingding
) => {if (!permission.includes(userId + ":" + bingding.value)) {el.style.display = "none";}
};</script><style lang="less" scoped>
</style>
 效果图:

  自定义指令-图片懒加载案例

import.meta.globEager vite获取文件下的所有图片

// glob 懒加载 是import函数得方式 () => import('')
// globEager 静态加载 是import xxx from 'xxx'的方式

new IntersectionObserver判断元素是否在可视区内

<template><hr /><h3>图片懒加载</h3><div><div v-for="(item, index) in arr" :key="index"><imgheight="500":data-index="item"v-lazy="item"width="360"alt=""/></div></div>
</template><script setup lang="ts">
import {ref,reactive,Directive,DirectiveBinding,
} from "vue";// 图片懒加载
// glob 懒加载 是import函数得方式 () => import('')
// globEager 静态加载 是import xxx from 'xxx'的方式
const images: Record<string, { default: string }> =import.meta.globEager("./assets/images/*.*");
let arr = Object.values(images).map((v) => v.default);let vLazy: Directive<HTMLImageElement, string> = async (el,binding
) => {let url = await import("./assets/vue.svg");el.src = url.default;// new IntersectionObserver判断元素是否在可视区内let observer = new IntersectionObserver((entries) => {console.log(entries[0], el);if (entries[0].intersectionRatio > 0 &&entries[0].isIntersecting) {setTimeout(() => {el.src = binding.value;observer.unobserve(el);}, 2000); // 加了延迟方便查看效果}});observer.observe(el);
};</script><style lang="less" scoped>
</style>
效果图

 以上所有完整的示例代码

A组件都是同个文件

<template><h3>自定义指令</h3><button @click="flag = !flag">开关</button><!-- 卸载 --><!--  <Av-if="flag"v-move-directive="{ background: 'red' }"></A> --><!-- 更新 aa.cookie是随意写的自定义修饰符 --><!-- <Av-move-directive.aa.cookie="{background: 'red',flag: flag,}"></A> --><!--   <hr /><h3>自定义函数简写 /v-move1-directive.aaa.cookie代表属性和修饰符</h3><input type="text" v-model="color" /><Av-move1-directive.aaa.cookie="{ background: color }"></A> --><!-- <hr /><h3>按钮鉴权案例</h3><div><button v-has-button="'shop:create'">新增</button><button v-has-button="'shop:edit'">编辑</button><button v-has-button="'shop:delete'">删除</button></div> --><hr /><h3>图片懒加载</h3><div><div v-for="(item, index) in arr" :key="index"><imgheight="500":data-index="item"v-lazy="item"width="360"alt=""/></div></div><!--<hr /><h3>自定义指令案例移动盒子</h3><div v-move class="box"><div class="header">按住头部可以移动</div><div>内容</div></div> -->
</template><script setup lang="ts">
import {ref,reactive,Directive,DirectiveBinding,
} from "vue";
import A from "./components/twenty_one_A.vue";
let flag = ref<boolean>(true);
let color = ref<string>("");type Value = {//这样才会提示background,帮助我们做内型推导background: string;
};const vMoveDirective: Directive = {// 自定义指令必须以v开头 Directivecreated: () => {console.log("created初始化====>");},beforeMount(...args: Array<any>) {console.log("beforeMount初始化一次=======>");console.log("args==>", args); // 共有4个参数 1是组件的元素 2是dir 3.是虚拟Dom 4.是上一次更新的dom//获取到这些内容后在元素上做些操作},mounted(el: any, dir: DirectiveBinding<Value>) {el.style.background = dir.value.background;console.log("mounted初始化========>");},beforeUpdate() {console.log("beforeUpdate更新之前");},updated() {console.log("updated更新结束");},beforeUnmount(...args: Array<any>) {console.log(args);console.log("======>beforeUnmount卸载之前");},unmounted(...args: Array<any>) {console.log(args);console.log("======>unmounted卸载完成");},
};// 函数简写
type Dir = {background: string;
};const vMove1Directive: Directive = (el: HTMLElement, // 获取的是A组件的实例binding: DirectiveBinding<Dir> // 指令上的值
) => {el.style.background = binding.value.background;
};// 按钮鉴权localStorage.setItem("userId", "cookie1");//mock后台返回的数据
const permission = ["cookie1:shop:edit","cookie1:shop:create",// "cookie1:shop:delete",
];
const userId = localStorage.getItem("userId") as string;
const vHasButton: Directive<HTMLElement, string> = (el,bingding
) => {if (!permission.includes(userId + ":" + bingding.value)) {el.style.display = "none";}
};// 图片懒加载
// glob 懒加载 是import函数得方式 () => import('')
// globEager 静态加载 是import xxx from 'xxx'的方式
const images: Record<string, { default: string }> =import.meta.globEager("./assets/images/*.*");
let arr = Object.values(images).map((v) => v.default);let vLazy: Directive<HTMLImageElement, string> = async (el,binding
) => {let url = await import("./assets/vue.svg");el.src = url.default;// new IntersectionObserver判断元素是否在可视区内let observer = new IntersectionObserver((entries) => {console.log(entries[0], el);if (entries[0].intersectionRatio > 0 &&entries[0].isIntersecting) {setTimeout(() => {el.src = binding.value;observer.unobserve(el);}, 2000);}});observer.observe(el);
};// 自定义指令案例移动盒子
const vMove: Directive = {mounted(el: HTMLElement) {console.log(el.firstElementChild); // 获取父元素内的第一个节点console.log(el.lastElementChild); // 获取父元素内的最后一个节点let moveEl = el.firstElementChild as HTMLElement;const mouseDown = (e: MouseEvent) => {//鼠标点击物体那一刻相对于物体左侧边框的距离=点击时的位置相对于浏览器最左边的距离-物体左边框相对于浏览器最左边的距离console.log(e.clientX,e.clientY,"-----起始",el.offsetLeft);let X = e.clientX - el.offsetLeft;let Y = e.clientY - el.offsetTop;const move = (e: MouseEvent) => {el.style.left = e.clientX - X + "px";el.style.top = e.clientY - Y + "px";console.log(e.clientX, e.clientY, "---改变");};document.addEventListener("mousemove", move);document.addEventListener("mouseup", () => {document.removeEventListener("mousemove", move);});};moveEl.addEventListener("mousedown", mouseDown);},
};
</script><style lang="less" scoped>
</style>

20 vue3之自定义hooks-CSDN博客文章浏览阅读63次。Vue3 自定义Hook的作用主要用来处理复用代码逻辑的一些封装Vue3 的 hook函数 相当于 vue2 的 mixin, 不同在与hooks 是函数Vue3 的 hook函数 可以帮助我们提高代码的复用性, 让我们能在不同的组件中都利用 hooks 函数这个在vue2 就已经有一个东西是Mixinsmixins就是将这些多个相同的逻辑抽离出来,各个组件只需要引入mixins,就能实现一次写代码,多组件受益的效果。https://blog.csdn.net/qq_37550440/article/details/142548504?sharetype=blogdetail&sharerId=142548504&sharerefer=PC&sharesource=qq_37550440&spm=1011.2480.3001.8118

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

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

相关文章

Java增强for循环遍历集合删除指定值不安全问题

在这里因为remove方法有两种参数&#xff0c;一种是对象&#xff08;删除此元素&#xff09;&#xff0c;一种是Integer &#xff08;删除此下标对应的元素&#xff09;。恰好我对象类型就是Integer&#xff0c;所以或默认为删除下标对应元素&#xff0c;造成下标越界不安全。可…

Python的异步编程

什么是协程&#xff1f; 协程不是计算机系统提供&#xff0c;程序员人为创造。 协程也可以被称为微线程&#xff0c;是一种用户态内的上下文切换技术。简而言之&#xff0c;其实就是通过一个线程实现代码块相互切换执行。 实现协程有那么几种方法&#xff1a; greenlet&…

高校体育场小程序|高校体育场管理系统系统|体育场管理系统小程序设计与实现(源码+数据库+文档)

高校体育场管理系统小程序 目录 体育场管理系统小程序设计与实现 一、前言 二、系统功能设计 三、系统实现 四、数据库设计 1、实体ER图 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍&#xff1a;✌️大厂码农|毕设布道…

关于Elastic Search与MySQL之间的数据同步

目录 前言 思路分析 同步调用 异步通知 监听binlog 选择 实现数据同步 思路 运行项目 声明交换机、队列 1&#xff09;引入依赖 2&#xff09;声明队列交换机名称 3&#xff09;声明队列交换机 发送MQ消息 接收MQ消息 前言 Elastic Search中的酒店数据来自于MyS…

C++进阶(3): 二叉搜索树

二叉搜索树的概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一颗空树&#xff0c;或者具有以下性质的二叉树&#xff1a; 若它的左子树不为空&#xff0c;则左子树上所有的节点的值都小于等于 根节点的值若它的右子树不为空&#xff0c;则右子树上所有的节点的值都大于等…

指针(4)

目录 1. 数组名的理解 但是有两个例外 sizeof(数组名)&#xff0c; • &数组名 2. ⼀维数组传参的本质 2.1指针打印数组 3.冒泡排序 4.二级指针 5 指针数组 5.1 指针数组模拟二维数组 1. 数组名的理解 前面数组中提到 数组名的地址就是首元素的地址&#xff0c; 代…

国庆节快乐

葡萄城在这里祝大家国庆快快乐&#xff1a; 10月葡萄城活动&#xff1a; 公开课 【从软件应用走向数据应用——葡萄城技术赋能数据挖掘】 新版本发布&#xff1a; 活字格 V10.0 Update1新版本发布

【cache】浅析四种常用的缓存淘汰算法 FIFO/LRU/LFU/W-TinyLFU

本文浅析淘汰策略与工作中结合使用、选取&#xff0c;并非针对算法本身如何实现的 文章目录 FIFOLFULRUW-TinyLFU实践与优化监控与调整 FIFO first input first output &#xff0c; 先进先出&#xff0c;即最早存入的元素最先取出&#xff0c; 典型数据结构代表&#xff1a;…

2024年10月1日历史上的今天大事件早读

989年10月1日 北宋政治家范仲淹出生 1814年10月1日 反法联盟各参加国在奥地利首都维也纳召开会议 1927年10月1日 苏联开始实施第一个五年计划 1930年10月1日 中国收回威海卫租界 1931年10月1日 日本人在东北拼凑伪政权 1938年10月1日 大型纪录片《延安与八路军》开拍 194…

65.【C语言】联合体

目录 目录 1.定义 2.格式 3.例题 答案速查 分析 4.练习 答案速查 分析 5.相同成员的联合体和结构体的对比 6.联合体的大小计算 2条规则 答案速查 分析 练习 答案速查 分析 7.联合体的优点 8.匿名联合体 1.定义 和结构体有所不同,顾名思义:所有成员联合使用同…

VS code user setting 与 workspace setting 的区别

VS code user setting 与 workspace setting 的区别 引言正文引言 相信有不少开始接触 VS code 的小伙伴会有疑问,user setting 与 workspace setting 有什么区别呢?这里我们来说明一下 正文 首先,当我们使用 Ctrl + Shift + P 打开搜索输入 setting 后,可以弹出 4 个se…

【2023工业3D异常检测文献】M3DM: 基于混合融合的多模态工业异常检测方法

Multimodal Industrial Anomaly Detection via Hybrid Fusion 1、Background 随着3D传感器的发展&#xff0c;最近发布了具有2D图像和3D点云数据的MVTec-3D AD数据集&#xff0c;促进了多模态工业异常检测的研究。 无监督异常检测的核心思想是找出正常表示与异常之间的差异。…

Android Studio Dolphin 中Gradle下载慢的解决方法

我用的版本Android Studio Dolphin | 2021.3.1 Patch 1 1.Gradle自身的版本下载慢 解决办法&#xff1a;修改gradle\wrapper\gradle-wrapper.properties中的distributionUrl 将https\://services.gradle.org/distributions为https\://mirrors.cloud.tencent.com/gradle dis…

2024 maya的散布工具sppaint3d使用指南

目前工具其实可以分为三个版本 1 最老的原版 时间还是2011年的&#xff0c;只支持python2版的maya 2 作者python3更新版 后来作者看maya直到2022上还是没有类似好用方便的工具&#xff0c;于是更新到了2022版本 这个是原作者更新的2022版本&#xff0c;改成了python3&#…

SpringBoot——基础配置

但是还需要删除pom.xml中的标签——模板的文件也同样操作 banner的选项——关闭 控制台 日志 banner图片的位置——还会分辨颜色 在 Java 的日志框架&#xff08;如 Logback、Log4j2 等&#xff09;中&#xff0c;logging.level.root主要用于设置根日志记录器的日志级别…

IIS开启后https访问出错net::ERR_CERT_INVALID

安装ArcGIS server和portal等&#xff0c;按照说明上&#xff0c;先开启iis&#xff0c;在安装server、datastore、portal、webadapter等&#xff0c;遇到一些问题&#xff1a; 问题1 访问http正常&#xff0c;访问https出错&#xff1a; 解决方案 从这里找到解决方案&…

TDesign组件库+vue3+ts 如何视觉上合并相同内容的table列?(自定义合并table列)

背景 当table的某一列的某些内容相同时&#xff0c;需要在视觉上合并这一部分的内容为同个单元格 如上图所示&#xff0c;比如需要合并当申请人为同个字段的列。 解决代码 <t-table:data"filteredData":columns"columns":rowspan-and-colspan"…

宝塔部署vue项目出现的各种问题

使用宝塔面板&#xff0c;网站页面&#xff0c;构建php静态网页 问题一&#xff1a;图片等静态资源无法加载 找到真正请求的url&#xff0c; 然后在项目目录下面创建对应的目录&#xff0c;将资源放入 问题二&#xff1a;刷新出现404 在这里任意位置添加 ## 添加上这个配…

计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-09-28

计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-09-28 目录 文章目录 计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-09-28目录前言1. Cognitive phantoms in LLMs through the lens of latent variables摘要研究背景问题与挑战创新点算法模型实验效果…

业务封装与映射 -- AMP BMP GMP

概述 不同单板支持不同的封装模式&#xff0c;主要包括: AMP (Asynchronous Mapping Procedure&#xff0c;异步映射规程)BMP (Bit-synchronous Mapping Procedure&#xff0c;比特同步映射规程)GMP (Generic Mapping Procedure&#xff0c;通用映射规程) AMP/BMP&#xff1a…