【vue高频面试题】第 23 题:Vue3 自定义指令(directive)完整解析

第 23 题:Vue3 自定义指令(directive)完整解析


🎯 一、什么是自定义指令?

自定义指令用于在DOM 层 封装可复用的逻辑,

适合处理:聚焦、懒加载、权限、拖拽、固定吸顶、长按 等场景。

Vue 提供两个层级:

  • 全局指令(app.directive)
  • 组件局部指令(directives: { xxx })

用途与组件不同:

  • 组件 → 处理 UI 和业务逻辑
  • 指令 → 只负责 DOM 操作

🎯 二、Vue3 自定义指令生命周期(重点)

Vue3 中指令共有 5 个钩子:

  1. created(el, binding)
  2. beforeMount
  3. mounted
  4. beforeUpdate
  5. updated
  6. beforeUnmount
  7. unmounted

最常用:mounted 和 updated。


🎯 三、最简单示例:v-focus(输入框自动聚焦)

局部指令

xml 复制代码
<input v-focus />

<script>
export default {
  directives: {
    focus: {
      mounted(el) {
        el.focus()
      }
    }
  }
}
</script>

🎯 四、Vue3 自定义指令原理(高频面试点)

Vue 在编译模板时,会将所有指令解析为 指令对象,在渲染 DOM 时调用相应的指令钩子,对 DOM 进行增强。

执行流程:

  1. 模板编译成 VNode 时指令信息会被记录
  2. 渲染时调用 mounted(el, binding)
  3. 更新时调用 updated(el, binding)
  4. 销毁时调用 unmounted(el)

本质是:

VNode 生命周期 + 指令钩子 = DOM 增强


🎯 五、常见指令面试案例(重要)

1️⃣ 图片懒加载 v-lazy

scss 复制代码
mounted(el, binding) {
  const observer = new IntersectionObserver(([entry]) => {
    if (entry.isIntersecting) {
      el.src = binding.value
      observer.unobserve(el)
    }
  })
  observer.observe(el)
}

技术点:使用 IntersectionObserver 监听是否进入视口。


2️⃣ 权限指令 v-permission

scss 复制代码
mounted(el, binding) {
  const userRoles = store.state.user.roles
  if (!userRoles.includes(binding.value)) {
    el.remove() // 无权限则移除节点
  }
}

很多后台系统都会问这个。


3️⃣ 长按指令 v-longpress

javascript 复制代码
mounted(el, binding) {
  let timer
  el.addEventListener("mousedown", () => {
    timer = setTimeout(() => binding.value(), 500)
  })
  el.addEventListener("mouseup", () => clearTimeout(timer))
}

🎯 六、binding 参数(面试必问)

binding 包含:

arduino 复制代码
binding = {
  instance,           // 组件实例
  value,              // 传入的值
  oldValue,           // 旧值
  arg,                // 指令参数
  modifiers           // 修饰符
}

用法示例:

ini 复制代码
<div v-demo:color.red="msg"></div>

解析:

  • arg = 'color'
  • modifiers = { red: true }
  • value = msg

🎯 七、关键知识点 - 什么时候用指令?什么时候用组件?

用组件? 用指令?
有 UI 和模板结构 不需要模板结构
需要逻辑复用 + DOM 只需要封装 DOM 操作
有状态 无状态逻辑(纯 DOM)
适合全局组件库 适合权限、懒加载、拖拽

一句话:

只要是"DOM 行为",尽量用指令;
数据逻辑 + UI 就应该用组件。


🎯 八、面试官常问追问(附最佳答案)


追问 1:Vue3 的指令和 Vue2 有哪些不同?

答:

  • Vue3 去掉了 bind 和 inserted
  • 新增了 created、beforeMount
  • 生命周期更加统一
  • binding.instance 替代 vnode.component

追问 2:指令能在 setup 中使用吗?

不能直接在 setup return 中注册,但可以写成一个对象:

javascript 复制代码
const vFocus = {
  mounted(el) { el.focus() }
}

return { vFocus }

追问 3:指令和 watch 哪个性能更好?

使用指令,因为:

  • watch 会触发计算
  • 指令只在 DOM 层操作,不依赖响应式系统
  • 性能更高

追问 4:指令能否访问组件内部变量?

可以,通过 binding.instance

复制代码
binding.instance.xxx

🎯 九、一句话总结

Vue3 自定义指令是操作 DOM 的利器,不参与组件逻辑,拥有独立生命周期,常用于懒加载、权限、拖拽、聚焦等场景。

相关推荐
Highcharts.js7 分钟前
智能数据分析组件Orbit 正式发布与快速上手体验教程
前端·人工智能·信息可视化·数据分析系统·highcharts·orbit·智能可视化
螺丝钉tina44 分钟前
[Playwright ][16]Playwright + TypeScript API 自动化测试实战:API测试
前端·javascript·typescript
小天源1 小时前
智叟云集系统 · 架构与职责分层
服务器·前端·数据库
Highcharts.js3 小时前
React 中原生支持使用 JSX 组件配置自定义表格 Highcharts Grid
前端·javascript·react.js·前端框架·jsx·highcharts·自定义表格
薛定谔的猫-菜鸟程序员3 小时前
Electron开发超详细教程(从入门到放弃)
前端·javascript·electron
最强小杰4 小时前
DeepSeek V4 Flash + Codex CLI 接入教程:原生 Responses API 适配,从配置到跑通收藏这篇就够了(2026)
java·前端·python·ai
考研保研资料分享4 小时前
2022环境工程保研北师大:三校专业追问、论文贡献与择校复盘
面试
静水leo4 小时前
使用 Whistle 拦截接口并模拟后端响应
前端
掘金者阿豪4 小时前
SQL Server数据迁移完成后,凌晨的数据库告警该怎么查?
前端·后端
JudithHuang4 小时前
React 嵌套路由与布局
前端·react.js·arcgis·react·react router