首页 > 其他分享 >vue3中的自定义指令

vue3中的自定义指令

时间:2023-04-10 14:47:21浏览次数:54  
标签:el console log 自定义 binding value 指令 vue3 event

1.适用到自定义指令的场景 防抖、图片懒加载、一键 Copy的功能、拖拽、页面水印、权限校验、输入框自动聚焦、相对时间转换、下拉菜单

2.个人需求:在后台系统中,有很多表单提交组件,其中很多限制数字且限制条件不同。最初使用

oninput="value=value.replace(/[^\d]/g,'')"

来显示只允许输入数字,后面发现bug,如果输入汉字,再输入数字,在弹窗中是无法读取该输入框内容的,如果再加入一些条件限制则会失去其便利性,有人说可以rule结合validate来实现,简单的的确可以。但是如果是数组对象里的数组对象里的某个值要校验呢?

功能的使用行吧。因此考虑替代自定义指令方案:

在src文件夹新建一个directive文件夹,存放自定义指令文件。新建index.ts将以后的所有的自定义指令自动导出,index.ts

import { App } from 'vue'

const modules = import.meta.glob('../directive/**/**.ts')
// 自动导入当前文件夹下的所有自定义指令(默认导出项)
export default (app:App<Element>):void => {
    for (const path in modules) {
        // 排除当前文件
        if(path !== '../directive/index.ts') {
            modules[path]().then((mod) => {
                mod.default(app)
            })
        }
    }
}

在main.ts中使用:

const app = createApp(App)
direct(app)

新建num.ts文件自定义指令:

import { App } from 'vue' export default (app: App<Element>): void => {     app.directive('num', {         created: (el, binding, vnode, prevNode) => {             console.log("第一个参数:当前绑定的DOM 元素", el);             console.log("---------------------------------------------");             console.log("第二个参数:是个对象", binding);             //使用指令的组件实例             console.log("binding.instance:第一个参数", binding.instance);             //传递给指令的值。             console.log("binding.value:第二个参数", binding.value);             //先前的值,仅在 beforeUpdate 和 updated 中可用。无论值是否有更改都可用。             console.log("binding.oldValue:第三个参数", binding.oldValue);             //传递给指令的参数(如果有的话)。例如在 v-my-directive:foo 中,arg 为 "foo"。             console.log("binding.arg:第四个参数", binding.arg);             //包含修饰符(如果有的话) 的对象。             console.log("binding.modifiers:第五个参数", binding.modifiers);             //一个对象,在注册指令时作为参数传递。             console.log("binding.dir:第六个参数", binding.dir);             console.log("---------------------------------------------");             console.log("第三个参数:当前元素的虚拟DOM 也就是Vnode", vnode);             console.log("---------------------------------------------");             console.log("第四个参数:prevNode 上一个虚拟节点,仅在 beforeUpdate 和 updated 钩子中可用 ", prevNode);             // console.log("初始化====>");         },         beforeMount(...args: Array<any>) {             // 在元素上做些操作             // console.log(args);             // console.log("初始化一次=======>");         },         mounted() {             // console.log("初始化========>");         },         beforeUpdate() {             // console.log("更新q前");         },         updated() {             // console.log("更新结束");         },         beforeUnmount() {             // console.log("======>卸载之前");         },         unmounted() {             // console.log("======>卸载完成");         }     }) }

二. 钩子函数以及生命周期钩子参数详解
  1. 钩子函数

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

  2. 生命周期钩子参数详解(每个钩子都有参数)

  • 第一个 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 钩子中可用

修改以后:

 import { App } from 'vue'  export default (app: App<Element>): void => {     app.directive('nums', {         mounted(el) {             console.log(el)             const reg = /^\+?[1-9][0-9]*$/             el.addEventListener('input', (event: any) => {                 console.log(event.target.value)                 if (!reg.test(event.target.value)) {                     event.target.value = ''                 }             })         }     })  }

测试,发现同样读取不到值,发现自定义事件以后把原有的触发事件阻止了。再次修改,手动触发:

export default (app: App<Element>): void => {
    app.directive('num', {
        mounted(el, binding, vnode: any) {
            console.log(vnode)
            const reg = /^\+?[1-9][0-9]*$/
            el.addEventListener('input', (event: any) => {
                // console.log(event.target.value)
                if (!reg.test(event.target.value)) {
                    event.target.value = ''
                }
                vnode.ctx.emit('update:modelValue', event.target.value)
            })
            el.addEventListener('change', (event: any) => {
                el.dispatchEvent(new Event('change ', { bubbles: true }))
                vnode.ctx.emit('update:modelValue', event.target.value)
            })
            el.addEventListener('clear', (event: any) => {
                el.dispatchEvent(new Event('clear ', { bubbles: true }))
                vnode.ctx.emit('update:modelValue', event.target.value)
            })
            el.addEventListener('focus', (event: any) => {
                el.dispatchEvent(new Event('focus ', { bubbles: true }))
                vnode.ctx.emit('update:modelValue', event.target.value)
            })
            el.addEventListener('blur', (event: any) => {
                el.dispatchEvent(new Event('blur ', { bubbles: true }))
                vnode.ctx.emit('update:modelValue', event.target.value)
            })
        }
    })
}

测试,可以了:最后加上一些提示,代码地址如下:

 https://gitee.com/yuexiayunsheng/vue3learn/blob/master/src/views/CustomInstruct.vue

参考:https://blog.csdn.net/MM_520131400/article/details/123931645

标签:el,console,log,自定义,binding,value,指令,vue3,event
From: https://www.cnblogs.com/foxing/p/17302796.html

相关文章

  • vue3 高德地图弹窗选址功能
    import{defineComponent,h}from'vue';importAMapLoaderfrom'@amap/amap-jsapi-loader';import{Input,AutoComplete,Modal,message}from'ant-design-vue';//首先需要引入Vue3的shallowRef方法(使用shallowRef进行非深度监听,因为在Vue3所......
  • 文件批量改名高手,文件怎么随机改名,支持自定义生成长度
    如何批量重命名多个文件呢?有没有简单一点的方法呢?小编的回答当然是有的啦,下面一起来试试这个新的技巧,希望能给大家带来帮助。所需工具安装一个文件批量改名高手文件素材若干操作步骤步骤1:运行【文件批量改名高手】,在“文件批量重命名”中,导入文件,支持多种导入文件的方式步骤2:确定都......
  • vue3 环境搭建部署
    安装node查看版本chenjun@chenjundeMacBook-Airuitest%node-vv18.7.0创建vue项目(⚠️注意项目名称小写)npminitvue@latest运行vue项目 1cd项目2npminstall3npmrundev ......
  • 自定义运行时异常(非检查异常)
    写一个类继承Exception或其子类,然后在其他类中使用该异常注意:自定义的异常为运行时异常,因为运行时异常为非检查异常,并不需要程序员显示的抛出异常,但是为了更好的去检测程序,所以自定义运行时异常自定义运行时异常的使用形式://自定义构造带......
  • 自定义 DNS 服务
    如果你在使用Deployment运行CoreDNS,则该Deployment通常会向外暴露为一个具有静态IP地址Kubernetes服务。kubelet使用--cluster-dns=<DNS服务IP>标志将DNS解析器的信息传递给每个容器。DNS名称也需要域名。你可在kubelet中使用--cluster-domain=<默认本地......
  • 解密prompt系列5. APE+SELF=自动化指令集构建代码实现
    上一章我们介绍了不同的指令微调方案,这一章我们介绍如何降低指令数据集的人工标注成本!这样每个人都可以构建自己的专属指令集,哈哈当然我也在造数据集进行时~介绍两种方案SELFInstruct和AutomaticPromptEngineer,前者是基于多样的种子指令,利用大模型的上下文和指令理解能力,......
  • 一统天下 flutter - widget 状态管理: 状态管理 - 自定义 controller
    一统天下flutterhttps://github.com/webabcd/flutter_demo作者webabcd一统天下flutter-widget状态管理:状态管理-自定义controller示例如下:lib\state\controller.dart/**状态管理-自定义controller**为自定义组件指定一个自定义controller后,就可......
  • 斯坦福 UE4 C++ ActionRoguelike游戏实例教程 08.创建主HUD & 自定义作弊指令
    斯坦福课程UE4C++ActionRoguelike游戏实例教程0.绪论概述本篇文章对应课程Lecture14,56-58节。本篇文章将会教你将之前创建的各种UMG控件统合到一个主控件上。此外,还会教你如何在C++中创建自定义作弊指令,并在游戏中使用控制台执行它。目录创建主HUD使用GameMode生成玩......
  • JAVA实体类-自定义Getter Setter
    ###案例一整个购物车存放的商品信息需要计算的属性需要重写get方法,保证每次获取属性都会进行计算privateBigDecimaltotalPrice;/***计算当前购物项总价*@return*/publicBigDecimalgetTotalPrice(){//等于单价*数量returnthis.price.multiply(......
  • C# Linq俩个list<Datarow> 取差集,并自定义字段
    可以自定义类,也可以从参考官网文档:Enumerable.Except方法(System.Linq)|MicrosoftLearnList<DataRow>list1=newList<DataRow>();List<DataRow>list2=newList<DataRow>();DataTabledataTable=newDataTable();dataTable......