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