Sunday面试指南

Vue 3 自定义指令怎么写?什么时候用指令,什么时候用组件?

下面是一段教学用的模拟面试。

🧑‍💻 面试官:Vue 自定义指令适合做什么?

🙋‍♂️ 我:可以封装对 DOM 的操作,比如自动聚焦。

🧑‍💻 面试官:带图标、错误提示和输入框的整块表单,也做成指令吗?

🙋‍♂️ 我:这种有结构和状态的部分,更适合组件。

🧑‍💻 面试官:如果指令绑定了事件监听,卸载时谁负责清理?指令放在多根节点组件上又会怎样?

指令负责复用「已有元素上的行为」,组件负责组织「一块界面」。先分清这两种职责,再讨论钩子。

面试速答(60 秒版)

Vue 自定义指令适合复用需要直接操作 DOM 的行为,比如聚焦、测量或对已有元素添加某种交互。

如果功能包含自己的界面结构、状态和子组件,通常应该做成组件,而不是用指令拼出一整块 UI。只想复用响应式逻辑,则可以考虑组合式函数。

指令通过 mounted、updated、unmounted 等钩子处理元素生命周期。需要长期保留的监听器、观察器或计时器,应当在卸载时清理。

实际使用时,我会尽量把指令放在明确的原生元素上。应用到组件时,它可能作用于组件根元素;多根节点组件没有唯一目标,不能假设指令能自动选择正确节点。也不能在服务端渲染阶段直接访问浏览器 DOM。

元素行为、界面、逻辑,分别复用

图:元素行为、界面、逻辑,分别复用。

知识点详解:指令、组件和组合式函数各负责什么?

从“自动聚焦”看指令的工作范围

假设弹窗打开后,需要让用户名输入框自动获得焦点。输入框本身由模板创建,指令只需要在元素挂载完成后调用 focus。

这就是适合指令的情况:它不负责创建输入框,也不负责决定表单长什么样,只为一个已经存在的元素增加行为。

TypeScript

import type { Directive } from "vue";
export const vFocus: Directive<HTMLInputElement, boolean> = {
  mounted(el, binding) {
    if (binding.value !== false) el.focus();
  },
  updated(el, binding) {
    if (binding.value && !binding.oldValue) el.focus();
  },
};

示例只在值从假变真时重新聚焦,避免每次更新都抢走用户的输入焦点。它使用 Vue 浏览器指令 API,Python 没有同一套官方实现。

钩子不是随便换名字的事件回调

mounted 表示元素已经挂载,可以进行依赖真实元素的操作;updated 用来响应更新,需要结合 binding 的新旧值判断是否真的要重复执行。

unmounted 则是释放资源的重要位置。假设指令创建 ResizeObserver,卸载时就应 disconnect;如果注册事件监听,则需要保留对应的处理函数,才能正确 removeEventListener。

不能在 mounted 中创建一个匿名函数,卸载时再创建另一个匿名函数,认为它们“长得一样”就能移除。监听器的函数身份必须一致。

完整钩子和 binding 内容可以核对 Vue 自定义指令文档。

谁绑定资源,谁安排清理

图:谁绑定资源,谁安排清理。

什么时候应该换成组件或组合式函数?

要复用的内容更适合
给已有输入框聚焦自定义指令
输入框、标签、错误提示组成的界面组件
表单校验状态、请求状态等逻辑组合式函数

有些需求可以配合使用。比如组件负责表单结构,组合式函数负责校验,指令只处理特殊 DOM 行为。不要为了“复用”把三种职责全部塞进同一个指令。

为什么不推荐随意把指令放在组件上?

组件不是一个确定的 DOM 元素。单根组件通常可以把指令应用到根节点,但这会让调用方依赖组件内部的根节点选择。

如果组件改成多根节点,或者根节点换了,指令目标可能就不再满足原来假设。为了稳定的行为,可以让组件通过 prop 或显式方法控制聚焦,或者直接将指令绑定到内部对应元素。

此外,SSR 环境没有普通浏览器 DOM。只能在客户端有效钩子中执行 DOM 操作;需要服务端输出属性时,应按 Vue 提供的服务端指令机制处理。

面试官继续追问

权限按钮可以只用指令隐藏吗?

可以作为界面呈现手段,但不能当成权限校验。用户可以绕过页面直接请求接口,后端仍要验证权限。

每次 updated 都重新绑定监听器,可以吗?

如果不清理旧监听,会叠加处理和泄漏。应该只在需要时更新,或者先移除旧资源再创建新资源。

指令适合异步获取数据吗?

不是完全不能,但数据状态和请求生命周期通常更适合组件或组合式函数。除非异步操作明确服务于某个元素行为,否则容易让职责混乱。

面试速记卡

  • 指令:复用已有 DOM 元素上的行为。
  • 组件:组织界面结构与状态。
  • 组合式函数:复用响应式业务逻辑。
  • 生命周期:创建的监听、观察器和定时器需要清理。
  • 组件与 SSR:不要假设始终有唯一可操作的浏览器元素。

公司面试真题

这道题暂未收录可核验的公司真题来源。你可以先阅读本文解析,或浏览已收录的公司面试真题。

浏览公司面试真题 →
简历汪永久免费在线制作简历,模板直接套用、导出无水印,永久免费、下载免费,不需要付费解锁任何功能。去写简历