自定义指令
文章目录前言一、什么是自定义指令1.1 定义1.2 与组件的区别二、指令钩子2.1 Vue 3 钩子2.2 Vue 2 vs Vue 3 钩子对照2.3 钩子参数三、binding 对象3.1 常用属性3.2 示例四、注册方式4.1 全局注册4.2 局部注册script setup五、常见指令实现5.1 v-focus自动聚焦5.2 v-lazy图片懒加载5.3 v-permission权限控制5.4 v-debounce输入防抖5.5 v-click-outside点击外部关闭六、函数式指令6.1 简写形式七、面试聚焦7.1 Vue 3 指令钩子变化7.2 如何访问组件实例7.3 script setup 局部注册命名八、易混淆点九、思考与练习总结前言自定义指令用于对普通 DOM 元素进行底层操作适合处理聚焦、懒加载、权限控制等横切逻辑。本篇会讲清楚指令钩子与参数全局注册 vs 局部注册常见指令实现v-focus、v-lazy、v-permissionVue 2 与 Vue 3 指令钩子变化一、什么是自定义指令1.1 定义自定义指令用于在 DOM 元素挂载、更新、卸载时执行底层操作适合直接操作 DOM的场景。!-- 内置指令v-if、v-for、v-model -- !-- 自定义指令v-focus、v-lazy、v-permission -- input v-focus /1.2 与组件的区别对比项组件自定义指令粒度完整 UI 单元单个 DOM 元素用途复用 UI 结构复用 DOM 行为典型场景Button、Modal聚焦、懒加载、权限二、指令钩子2.1 Vue 3 钩子constmyDirective{// 元素挂载到 DOM 后调用mounted(el,binding,vnode,prevVnode){},// 元素更新后调用binding 变化时updated(el,binding,vnode,prevVnode){},// 元素卸载前调用beforeUnmount(el,binding,vnode,prevVnode){},// 元素卸载后调用unmounted(el,binding,vnode,prevVnode){}}2.2 Vue 2 vs Vue 3 钩子对照Vue 2Vue 3bindbeforeMountinsertedmountedupdatebeforeUpdatecomponentUpdatedupdatedunbindunmounted2.3 钩子参数mounted(el,binding,vnode,prevVnode){// el指令绑定的 DOM 元素// binding指令绑定信息对象// vnodeVue 虚拟节点// prevVnode更新前的虚拟节点仅 updated 有值}三、binding 对象3.1 常用属性mounted(el,binding){binding.value// 指令绑定的值如 v-focustrue 中的 truebinding.oldValue// 更新前的值仅 updated 可用binding.arg// 指令参数如 v-color:red 中的 redbinding.modifiers// 修饰符对象如 v-click.stop 中的 { stop: true }binding.instance// 当前组件实例Vue 3 无 this通过此访问binding.dir// 指令定义对象}3.2 示例!-- v-demo:foo.barbaz -- !-- arg: foo -- !-- modifiers: { bar: true } -- !-- value: baz -- input v-permission:edit[admin] / !-- arg: edit -- !-- value: [admin] --四、注册方式4.1 全局注册// main.jsimport{createApp}fromvueimportAppfrom./App.vueconstappcreateApp(App)// 注册指令app.directive(focus,{mounted(el){el.focus()}})app.mount(#app)!-- 任意组件中使用 -- input v-focus /4.2 局部注册script setupscript setup // 局部指令变量名必须以 v 开头 驼峰 const vFocus { mounted(el) { el.focus() } } /script template input v-focus / /templatescript setup // 从外部文件导入 import { vLazy } from /directives/lazy /script template img v-lazyimageUrl / /template五、常见指令实现5.1 v-focus自动聚焦constvFocus{mounted(el){el.focus()}}// 使用// input v-focus /// input v-focusshouldFocus / 条件聚焦constvFocus{mounted(el,binding){if(binding.value!false){el.focus()}}}5.2 v-lazy图片懒加载constvLazy{mounted(el,binding){constobservernewIntersectionObserver(([entry]){if(entry.isIntersecting){el.srcbinding.value observer.unobserve(el)}})observer.observe(el)},unmounted(el){// 清理 observer需在 mounted 中保存引用}}// 使用// img v-lazyimageUrl /// 完整版含占位图和清理constvLazy{mounted(el,binding){el.srcbinding.arg||placeholder.jpg// 占位图constobservernewIntersectionObserver(([entry]){if(entry.isIntersecting){el.srcbinding.value observer.unobserve(el)}})observer.observe(el)el._lazyObserverobserver},unmounted(el){el._lazyObserver?.unobserve(el)el._lazyObservernull}}5.3 v-permission权限控制constvPermission{mounted(el,binding){const{value}bindingconstuserRolesgetUserRoles()// 从 store 或 inject 获取consthasPermissionvalue.some(roleuserRoles.includes(role))if(!hasPermission){// 无权限移除元素或禁用el.parentNode?.removeChild(el)// 或 el.disabled true}}}// 使用// button v-permission[admin]删除/button// button v-permission[admin, editor]编辑/button5.4 v-debounce输入防抖constvDebounce{mounted(el,binding){constdelaybinding.arg?parseInt(binding.arg):300consthandlerbinding.value// 传入的回调函数lettimernullel._debounceHandler(e){clearTimeout(timer)timersetTimeout(()handler(e),delay)}el.addEventListener(input,el._debounceHandler)},unmounted(el){el.removeEventListener(input,el._debounceHandler)}}// 使用// input v-debounce:500onSearch /5.5 v-click-outside点击外部关闭constvClickOutside{mounted(el,binding){el._clickOutside(e){if(!el.contains(e.target)){binding.value()// 执行回调}}document.addEventListener(click,el._clickOutside)},unmounted(el){document.removeEventListener(click,el._clickOutside)}}// 使用下拉菜单点击外部关闭// div v-click-outsidecloseDropdown.../div六、函数式指令6.1 简写形式如果指令只在mounted和updated中触发相同逻辑可以简写为函数// 完整写法app.directive(color,{mounted(el,binding){el.style.colorbinding.value},updated(el,binding){el.style.colorbinding.value}})// 函数式简写mounted 和 updated 都会调用app.directive(color,(el,binding){el.style.colorbinding.value})七、面试聚焦7.1 Vue 3 指令钩子变化// Vue 2: bind, inserted, update, componentUpdated, unbind// Vue 3: beforeMount, mounted, beforeUpdate, updated, beforeUnmount, unmounted// 命名与组件生命周期对齐7.2 如何访问组件实例// Vue 2: 指令钩子中有 this// Vue 3: 无 this通过 binding.instance 访问mounted(el,binding){constinstancebinding.instance console.log(instance.someData)}7.3 script setup 局部注册命名// 变量名 vFocus → 模板中使用 v-focus// 变量名 vLazyLoad → 模板中使用 v-lazy-loadconstvFocus{mounted(el){el.focus()}}八、易混淆点指令无 thisVue 3 指令钩子中没有this通过binding.instance访问组件实例。binding.oldValue仅在updated钩子中可用用于对比新旧值。局部注册命名script setup中变量名必须以v开头如vFocus→v-focus。指令 vs 组件指令操作单个 DOM 元素组件是完整 UI 单元。记得清理在unmounted中移除事件监听、Observer 等避免内存泄漏。九、思考与练习1.自定义指令适合什么场景解析需要直接操作 DOM 的横切逻辑如聚焦、懒加载、权限控制、防抖、点击外部关闭等。不适合复杂 UI 复用用组件。2.binding 对象有哪些常用属性解析value绑定值、arg参数、modifiers修饰符、oldValue旧值仅 updated、instance组件实例。3.如何实现 v-focus 指令constvFocus{mounted(el){el.focus()}}4.Vue 3 指令如何访问组件实例解析通过binding.instance不再有this上下文。5.局部注册指令在 script setup 中如何命名解析变量名以v开头 驼峰如vFocus对应模板中的v-focus。总结自定义指令对 DOM 元素进行底层操作提供 mounted/updated/unmounted 钩子bindingvalue、arg、modifiers、instance 等绑定信息注册方式全局app.directive()局部vXxx变量常见实现v-focus、v-lazy、v-permission、v-debounceVue 3 变化钩子命名对齐组件生命周期无 this

相关新闻

025、TOSA(Tensor Operator Set Architecture)标准介绍

025、TOSA(Tensor Operator Set Architecture)标准介绍

TOSA(Tensor Operator Set Architecture)标准介绍 上周帮团队排查一个跨框架模型部署的bug,现象很诡异:同一个ONNX模型,用ONNX Runtime跑推理结果正确,转成TFLite后在某个嵌入式设备上输出全乱码。折腾了两天,最后定位到是量化后的卷积算子在不同后端的行为不一致——有…

2026/6/18 14:30:44阅读更多 →
Day02—Lambda表达式彻底理解:不只是语法糖

Day02—Lambda表达式彻底理解:不只是语法糖

系列:Java后端工程师进阶之路 Day 2 定位:从匿名内部类到函数式接口,拆解Lambda底层实现机制(invokedynamic指令),对比性能差异 目录 一、从匿名内部类到Lambda:不只是少写几行 1.1 匿名内部…

2026/6/18 14:30:44阅读更多 →
如何选择适合制造企业的AI智能体类型

如何选择适合制造企业的AI智能体类型

一、引言制造企业的数字化进程,普遍面临一个真实困境:ERP管计划,MES管生产,PDM管图纸,OA管审批——每个系统都高效运转,但它们之间缺乏“共同语言”。订单数据在CRM生成,到了MES变成工单&#x…

2026/6/18 14:30:44阅读更多 →
机器学习模型可视化:四层诊断体系与工业级实操指南

机器学习模型可视化:四层诊断体系与工业级实操指南

1. 这不是画图,是给模型做“X光”和“体检报告”你有没有过这种经历:训练完一个线性回归模型,R高达0.92,心里美滋滋;可一拿到新数据,预测结果却像抛硬币——有时准得离谱,有时偏得离谱。或者&am…

2026/6/18 15:56:14阅读更多 →
NXP实时边缘软件实战:从Preempt-RT到TSN的工业物联网确定性架构

NXP实时边缘软件实战:从Preempt-RT到TSN的工业物联网确定性架构

1. 项目概述:工业物联网的确定性基石在工业自动化、机器人控制、汽车电子这些领域里,系统响应的“准时性”和“确定性”远比“快”更重要。想象一下,一个机械臂的控制指令晚了几个毫秒,或者一条生产线上的传感器数据因为网络拥堵而…

2026/6/18 15:56:14阅读更多 →
免费开源几何字体Outfit:9种字重打造品牌设计新革命

免费开源几何字体Outfit:9种字重打造品牌设计新革命

免费开源几何字体Outfit:9种字重打造品牌设计新革命 【免费下载链接】Outfit-Fonts The most on-brand typeface 项目地址: https://gitcode.com/gh_mirrors/ou/Outfit-Fonts 还在为品牌设计寻找完美字体吗?Outfit字体就是你的终极解决方案&#…

2026/6/18 15:56:14阅读更多 →
RTX 3090本地部署FLUX.2实战指南:显存优化与精度控制

RTX 3090本地部署FLUX.2实战指南:显存优化与精度控制

1. 项目概述:为什么一个RTX 3090能跑动FLUX.2,又为什么它值得你花三小时调通FLUX.2不是某个厂商发布的消费级软件,而是由Black Forest Labs开源的一套高保真图像生成模型架构——它不叫“Stable Diffusion的升级版”,而是一次底层…

2026/6/18 15:56:14阅读更多 →
Flux AI图像生成器实战指南:高精度可控文生图工作流

Flux AI图像生成器实战指南:高精度可控文生图工作流

1. 这不是又一个“AI画图工具测评”,而是一份 Flux 实战手记 Flux AI Image Generator——这个名字最近在设计圈、内容创作群和独立开发者私聊里出现的频率,高得有点反常。它不靠铺天盖地的广告,也不靠明星代言,而是靠一批批实际用…

2026/6/18 15:56:14阅读更多 →
LLaMA微调、PaLM-E对齐与Consistency Model实战指南

LLaMA微调、PaLM-E对齐与Consistency Model实战指南

1. 这不是一份“新闻简报”,而是一份AI从业者三月实战手记2023年3月的AI圈,没有冷场,只有加速。如果你在当月打开过Hugging Face模型库、刷过arXiv首页、或者调试过一次API调用延迟,你大概率会感受到一种明确的节奏变化&#xff1…

2026/6/18 15:51:09阅读更多 →
ZigBee HA智能家居开发实战:从集群模型到NXP JN516x代码实现

ZigBee HA智能家居开发实战:从集群模型到NXP JN516x代码实现

1. ZigBee HA:智能家居的“通用语言”与开发基石如果你正在或计划踏入智能家居设备开发领域,尤其是基于ZigBee协议,那么“ZigBee Home Automation”这个名词你一定不陌生。它不仅仅是ZigBee联盟定义的一套应用层规范,更是确保不同…

2026/6/18 0:00:24阅读更多 →
Java毕设选题推荐:基于 Spring Boot 的个人随笔博客运维管理系统的设计与实现 基于 Spring Boot 的用户原创博客分享社区【附源码、mysql、文档、调试+代码讲解+全bao等】

Java毕设选题推荐:基于 Spring Boot 的个人随笔博客运维管理系统的设计与实现 基于 Spring Boot 的用户原创博客分享社区【附源码、mysql、文档、调试+代码讲解+全bao等】

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/6/18 0:00:24阅读更多 →
JN517x嵌入式开发实战:看门狗、脉冲计数器与I2C接口的深度解析与避坑指南

JN517x嵌入式开发实战:看门狗、脉冲计数器与I2C接口的深度解析与避坑指南

1. 项目概述在嵌入式开发领域,尤其是基于NXP JN517x这类无线微控制器的项目中,系统稳定性和与外设的可靠交互是两大核心挑战。前者关乎产品能否在无人值守的复杂环境中长期运行,后者则决定了设备能否准确感知世界并与其他芯片“对话”。JN517…

2026/6/18 0:00:24阅读更多 →