Vue 核心高频问题详解(7 大高频考点)
Vue 核心高频问题详解(7 大高频考点)
覆盖:修饰符、自定义指令、v-if/v-show、v-model 适用范围、computed/watch/methods 区别、watch 对象新旧值区分、组件通信方案选型。
1. Vue 修饰符都有哪些?
Vue 修饰符主要分为 事件修饰符、v-bind 修饰符、v-model 修饰符、鼠标按键修饰符 四大类,用于简化常用操作,减少冗余代码。
1.1 事件修饰符(最常用)
.stop:阻止冒泡(event.stopPropagation()).prevent:阻止默认行为(event.preventDefault()).capture:使用捕获模式(默认冒泡).self:仅当事件源是当前元素本身才触发(不是子元素).once:只触发一次.passive:告诉浏览器不会调用preventDefault(),提升滚动性能(不能与.prevent同时使用)
示例:
<button @click.stop.prevent=“handleClick”>提交
<input @blur.once=“handleBlur” />
1.2 v-bind 修饰符(属性绑定相关)
.prop:按 DOM property 方式绑定(而非 attribute).camel:将短横线属性名转为驼峰(如view-box->viewBox).sync:(Vue 2 专属)简化父子双向绑定(Vue 3 用v-model机制替代)
1.3 v-model 修饰符(表单双向绑定)
.lazy:由input改为change时机(失焦/回车后更新).number:自动转数字(不可转则保留字符串).trim:自动去除首尾空格
**示例:**e
1.4 鼠标按键修饰符
.left:仅左键触发.right:仅右键触发.middle:仅中键触发
2. Vue 自定义指令的理解?
2.1 核心定义
当内置指令无法满足业务需求时,自定义指令用于封装可复用的 DOM 操作逻辑,直接作用于元素。
2.2 分类
- 全局指令:Vue2
Vue.directive()/ Vue3app.directive() - 局部指令:组件内
directives或<script setup>局部声明
2.3 Vue 3 指令生命周期钩子
createdbeforeMountmounted(最常用)beforeUpdateupdatedbeforeUnmountunmounted
2.4 示例:自动聚焦指令 v-focus
**Vue 3 全局注册:**s
const app = createApp(App)
app.directive(‘focus’, {
mounted(el) {
el.focus()
}
})**组件使用:**ue
局部注册(
3. v-if 和 v-show 的区别?
| 对比维度 | v-if | v-show |
|---|---|---|
| 核心实现 | 条件渲染:创建/销毁 DOM | 样式切换:display: none |
| 初始渲染 | 条件不满足则不渲染,成本低 | 无论条件如何都渲染,成本高 |
| 切换开销 | 高(增删 DOM) | 低(改样式) |
| 场景 | 低频切换、需要销毁释放资源 | 高频切换、仅显示隐藏 |
配合 <template> | 支持 | 不支持 |
| 生命周期 | 会触发(mount/unmount) | 不会触发(元素一直存在) |
| 与 v-for 优先级 | v-if 高(官方不建议同用) | v-show 低 |
总结:
- 低频切换/需要销毁组件:用
v-if - 高频切换/无需销毁:用
v-show
4. v-model 可以用在哪些表单上?
v-model 是 value 绑定 + 事件监听 的语法糖,支持绝大多数原生表单元素及自定义组件。
4.1 原生输入类
<input type="text/password/number"><textarea>
4.2 原生选择类
- 单选框:
<input type="radio">(同一个 v-model,不同 value) - 复选框:
<input type="checkbox">- 单个:绑定布尔值
- 多个:绑定数组(收集选中 value)
- 下拉框:
<select>- 单选:绑定单值
- 多选(
multiple):绑定数组
4.3 示例e
同意协议
男
女
Vue 3 通过 modelValue + update:modelValue 实现双向绑定(并支持自定义参数与修饰符扩展)。
5. computed、watch、methods 的区别?
5.1 computed(计算属性)
- 用途:派生新数据
- 特性:有缓存(依赖不变不重新计算)
- 返回:必须返回值
- 异步:不适合(会破坏“纯计算”语义)
5.2 watch(侦听器)
- 用途:监听变化执行 副作用(请求、异步、复杂联动)
- 特性:无缓存,每次变化都执行
- 返回:不要求返回值
- 支持配置:
deep、immediate等
5.3 methods(方法)
- 用途:封装可复用逻辑(可带参数)
- 特性:无缓存,每次调用都会执行
- 触发:事件触发/模板重新渲染时调用
5.4 对比表
| 维度 | computed | watch | methods |
|---|---|---|---|
| 核心用途 | 派生数据 | 监听变化做副作用 | 复用逻辑/事件处理 |
| 缓存 | 有 | 无 | 无 |
| 异步 | 不推荐 | 支持 | 支持 |
| 返回值 | 必须 | 不需要 | 可选 |
| 参数 | 不支持 | 不支持 | 支持 |
5.5 示例ue
全名:{{ fullName }}
当前时间:{{ formatTime(new Date()) }}
6. watch 监听对象时,新值和旧值一样,如何区分?
6.1 根因
监听对象/数组属于引用类型,属性变化时对象引用可能不变,导致 newVal 与 oldVal 指向同一块内存,看起来“新旧一样”。
6.2 方案一:deep + 深拷贝(常用)ue
6.3 方案二:手动保存旧值(更可控/更省性能)ue
### 6.4 注意事项JSON.parse(JSON.stringify())无法处理:函数、Symbol、undefined、循环引用等;复杂对象建议lodash.cloneDeepdeep: true有性能成本;若只关心单字段,建议:s
watch(() => user.value.age, (n, o) => {})
7. Vue 组件通讯?
组件通信本质是 数据传递(props/provide/store) + 事件触发(emit/bus),按关系选择方案。
7.1 父子组件通讯(最常用)
7.1.1 父 → 子:Propsue
ue姓名:{{ username }}
年龄:{{ age }}
7.1.2 子 → 父:自定义事件 emitue
#### 7.1.3 父调用子:ref + defineExpose(Vue 3)ue e7.2 兄弟组件通讯
方案 1:共同父组件中转(推荐)
兄弟 A emit 给父组件,父组件通过 props 传给兄弟 B(简单、清晰、易维护)。
方案 2:事件总线 Event Bus(Vue 3 常用 mitt)
安装:sh
npm install mitt创建总线:
// utils/eventBus.js
import mitt from ‘mitt’
const eventBus = mitt()
export default eventBus兄弟 A 发送:
7.3 跨级 / 深层组件通讯
方案 1:provide / inject(依赖注入)
祖先提供:
后代注入:ue
方案 2:全局状态管理(Pinia / Vuex)
- Pinia(Vue 3 推荐):更轻量、语法更简单、TS 友好
- Vuex:Vue2 常见,结构更“严格”
适合:用户信息、购物车、全局配置等多组件共享状态。
组件通信选型建议(总结)
| 组件关系 | 推荐方案 | 场景 |
|---|---|---|
| 父 → 子 | Props | 传递数据、单向流 |
| 子 → 父 | emit | 回传数据、触发父逻辑 |
| 父调用子方法 | ref + defineExpose | 弹窗/表单重置等 |
| 兄弟组件 | 父组件中转 / mitt | 简单中转或解耦通信 |
| 跨级组件 | provide/inject | 祖孙深层传递 |
| 全局共享 | Pinia/Vuex | 大型项目全局状态 |
额外手段:URL 参数、本地存储(localStorage/sessionStorage)适用于跨页面、刷新保持等场景。
更多推荐


所有评论(0)