news 2026/5/14 18:57:28

Vue 教程 自定义指令 + 生命周期全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Vue 教程 自定义指令 + 生命周期全解析

Vue 3 自定义指令 + 完整生命周期详解(2025–2026 实用版)

Vue 3 的自定义指令和组件生命周期是中高级开发中非常高频的内容,尤其在以下场景中几乎必考/必用:

  • 复杂表单(自动聚焦、输入防抖、权限显隐)
  • 拖拽、长按、水印、懒加载图片
  • 第三方库集成(图表 resize、虚拟滚动优化)
  • 调试/埋点/权限控制指令

下面把自定义指令组件生命周期放在一起讲解,因为它们在实际项目中经常结合使用。

一、Vue 3 组件生命周期(Composition API 版为主)

Vue 3 Composition API 使用onXXX钩子函数,Options API 则使用beforeCreate等选项。

阶段Options APIComposition API执行时机(最常用场景)是否异步
beforeCreatebeforeCreate—(不推荐)实例初始化之前,几乎不用同步
createdcreated—(不推荐)数据响应式处理完成,可访问 data / props同步
beforeMountbeforeMountonBeforeMount模板编译完成,即将挂载到 DOM 前同步
mountedmountedonMounted组件挂载完成,DOM 已渲染,可操作真实 DOM同步
beforeUpdatebeforeUpdateonBeforeUpdate数据变化 → 重新渲染前(可获取旧 DOM 状态)同步
updatedupdatedonUpdatedDOM 更新完成(注意:不要在这里修改响应式数据)同步
beforeUnmountbeforeUnmountonBeforeUnmount组件即将卸载(清理定时器、事件监听、订阅等)同步
unmountedunmountedonUnmounted组件完全卸载,DOM 已移除同步
activatedactivatedonActivatedkeep-alive 组件被激活时同步
deactivateddeactivatedonDeactivatedkeep-alive 组件失活时同步
errorCapturederrorCapturedonErrorCaptured捕获子组件错误(可返回 false 阻止抛出)同步
renderTrackedonRenderTracked响应式依赖被追踪(调试用)
renderTriggeredonRenderTriggered响应式依赖被触发重新渲染(调试用)
serverPrefetchonServerPrefetchSSR 预取数据(Nuxt / Vite SSR 常用)

最常用的 5 个钩子(日常开发占比 90%+)

  1. onMounted→ 获取 DOM、发起首次请求、初始化第三方库
  2. onBeforeUnmount/onUnmounted→ 清理定时器、事件监听、WebSocket 断开
  3. onUpdated→ DOM 更新后做一些微调(慎用,避免死循环)
  4. onActivated/onDeactivated→ keep-alive 场景(列表缓存、音频播放暂停)
  5. onErrorCaptured→ 组件级错误边界

代码示例(组合式 API 完整写法)

<script setup> import { ref, onMounted, onBeforeUnmount, onActivated, onDeactivated } from 'vue' const count = ref(0) let timer = null onMounted(() => { console.log('组件已挂载,可以操作 DOM') timer = setInterval(() => count.value++, 1000) }) onBeforeUnmount(() => { console.log('组件即将卸载,清理资源') clearInterval(timer) }) onActivated(() => { console.log('keep-alive 组件被激活') // 可重新启动轮询、视频播放等 }) onDeactivated(() => { console.log('keep-alive 组件失活') // 暂停轮询、视频等 }) </script>

二、Vue 3 自定义指令(v-xxx)

Vue 3 自定义指令的钩子函数比 Vue 2 精简了很多,统一成了6 个生命周期

钩子名称Options API 写法Composition API 写法(directive)执行时机是否传入 el
createdcreatedcreated指令绑定到元素时,在 beforeMount 之前
beforeMountbeforeMountbeforeMount元素挂载前
mountedmountedmounted元素挂载完成后(最常用)
beforeUpdatebeforeUpdatebeforeUpdate包含组件的 VNode 更新前
updatedupdatedupdated包含组件的 VNode 更新后
beforeUnmountbeforeUnmountbeforeUnmount元素卸载前
unmountedunmountedunmounted元素卸载后(最常用于清理)

最常用的是mounted+unmounted

三、自定义指令完整写法对比(三种方式)

方式1:全局注册(main.js / main.ts)
// main.jsimport{createApp}from'vue'importAppfrom'./App.vue'constapp=createApp(App)// 简单示例:v-focus 自动聚焦app.directive('focus',{mounted(el){el.focus()}})// 带清理的示例:v-longpress 长按 500ms 触发app.directive('longpress',{mounted(el,binding){lettimer=nullconststart=(e)=>{if(e.type==='click'&&e.button!==0)returntimer=setTimeout(()=>{binding.value(e)// 执行绑定的函数},500)}constcancel=()=>clearTimeout(timer)el.addEventListener('mousedown',start)el.addEventListener('touchstart',start)el.addEventListener('click',cancel)el.addEventListener('mouseout',cancel)el.addEventListener('touchend',cancel)el.addEventListener('touchcancel',cancel)// 推荐:把清理函数存到 el 上el._longpressCleanup=()=>{el.removeEventListener('mousedown',start)// ... 移除所有监听clearTimeout(timer)}},beforeUnmount(el){// 组件卸载时自动清理if(el._longpressCleanup){el._longpressCleanup()}}})app.mount('#app')
方式2:局部注册(<script setup>中使用)
<script setup> import { directive } from 'vue' const vPermission = { mounted(el, binding) { if (!hasPermission(binding.value)) { el.parentNode?.removeChild(el) } } } // 使用方式 defineOptions({ directives: { permission: vPermission } }) </script> <template> <button v-permission="'user:edit'">编辑</button> </template>
方式3:最推荐 —— 使用 composable 创建可复用指令
// composables/useFocus.jsimport{onMounted,onBeforeUnmount}from'vue'exportfunctionuseFocus(){constfocusDirective={mounted(el){el.focus()}}return{focusDirective}}
<script setup> import { useFocus } from '@/composables/useFocus' const { focusDirective } = useFocus() </script> <template> <input v-focus /> </template>

四、经典自定义指令合集(面试 + 项目必备)

指令名称功能常用钩子典型实现要点
v-focus自动聚焦mountedel.focus()
v-copy一键复制内容mounteddocument.execCommand
v-lazy-img图片懒加载mounted + IntersectionObserver
v-longpress长按触发mounted + 定时器清理
v-permission按钮级权限控制mounted判断权限 → remove 或 display:none
v-debounce输入防抖beforeUpdate + updated
v-resize监听元素尺寸变化mountedResizeObserver
v-watermark页面/元素水印mountedcanvas 或 div 叠加
v-draggable拖拽移动mounted + mousemove
v-loading自定义 loading 遮罩mounted / updated

五、总结:面试/项目常问的 10 个问题

  1. Vue 3 自定义指令比 Vue 2 少了哪些钩子?为什么?
  2. 自定义指令的elbindingvnodeprevNode分别是什么?
  3. 为什么推荐在beforeUnmountunmounted做清理?
  4. 如何让自定义指令支持修饰符(.prevent .stop 等)?
  5. v-model在自定义组件和自定义指令中的区别?
  6. 组件的onBeforeUnmount和指令的beforeUnmount执行顺序?
  7. 如何调试自定义指令(Vue Devtools 是否支持)?
  8. 自定义指令如何获取组件实例(getCurrentInstance)?
  9. 为什么很多 UI 库(如 Element Plus)大量使用自定义指令?
  10. 你写过哪些自定义指令?解决了什么痛点?

有具体想实现的自定义指令(比如 v-permission、v-lazy、v-draggable)需要完整代码示例吗?
或者想看某个生命周期钩子在真实业务中的典型用法?可以直接告诉我~

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/14 18:57:26

【网络安全】六大知名Web安全漏洞靶场

前言 如果想搞懂一个漏洞&#xff0c;最好的方法是先编写出这个漏洞&#xff0c;然后利用它&#xff0c;最后修复它。漏洞靶场模拟真实环境&#xff0c;它为网络安全人员提供了一个安全可控的平台&#xff0c;用于发现、评估和测试应用程序、系统或网络设备的安全漏洞。WEB漏洞…

作者头像 李华
网站建设 2026/5/14 18:57:27

2025年 Java 面试八股文

2025–2026 年 Java 后端面试&#xff08;尤其是金九银十、春招秋招、社招&#xff09;的高频“八股文”已经高度内卷化。面试官越来越倾向于**“八股文 项目场景 真实问题解决”**的组合考察。 下面给你一份2025–2026 年仍然最主流、最常被问到的八股文分类汇总&#xff0…

作者头像 李华
网站建设 2026/5/9 9:00:04

键盘改键神器,小巧实用

今天给大家推荐两款键盘改键和屏蔽的工具&#xff0c;有需要的小伙伴可以下载收藏。 第一款&#xff1a;KeyboardShield KeyboardShield是一款轻量级的键盘屏蔽和键位映射工具&#xff0c;体积大小仅124K&#xff0c;非常小巧&#xff0c;而且还是绿色单文件版&#xff0c;功能…

作者头像 李华
网站建设 2026/5/9 5:04:30

基于springboot的零工市场服务系统设计开发实现

零工市场服务系统的背景 随着共享经济和灵活就业模式的兴起&#xff0c;零工经济在全球范围内快速发展。传统就业模式难以满足企业和个人的多样化需求&#xff0c;零工市场通过数字化平台连接供需双方&#xff0c;提供高效灵活的用工解决方案。零工市场服务系统应运而生&#…

作者头像 李华
网站建设 2026/5/10 6:40:05

用Neo4j和G.V()可视化攻击图谱,加固你的网络安全

用攻击者的视角思考 从恶意软件加密挖矿攻击到勒索软件团伙&#xff0c;网络攻击的目标往往与任何抢劫行为相同&#xff1a;找到通往有价值资产的最短路径并迅速撤离。这本质上是路径寻找问题&#xff0c;这就是为什么长期以来人们都知道网络攻击者经常将其目标视为图网络&…

作者头像 李华