跳到主要内容
Vue 3 核心面试题与实战解析 | 极客日志
JavaScript 大前端
Vue 3 核心面试题与实战解析 Vue 3 面试核心知识点梳理,覆盖 Composition API、响应式原理、生命周期、组件通信及常用指令。通过 20 道高频真题结合代码示例,深入解析 ref/reactive 区别、setup 函数用法、Teleport/Suspense 新特性以及 v-model 实现原理。适合前端开发者系统复习框架升级点与工程化实践,快速掌握 Vue 3 技术栈关键能力。
极光 发布于 2026/1/18 更新于 2026/5/13 14 浏览Vue 3 核心面试题与实战解析
本文梳理了 Vue 3 面试中高频出现的 20 道核心问题,涵盖 Composition API、响应式系统(ref / reactive)、生命周期钩子、组件通信、Teleport、Suspense 及自定义指令等关键知识点。每道题均配有代码示例与原理说明,适合前端开发者系统复习框架升级点与工程化实践。
1. Vue 3 和 Vue 2 的区别是什么?
考察点: 理解 Vue 3 相比 Vue 2 的主要改进。
Vue 3 在架构和性能上做了显著优化。最核心的变化在于响应式系统从 Object.defineProperty 升级为 Proxy,这使得 Vue 3 能更好地处理数组和对象的变化检测。此外,Vue 3 采用模块化架构支持 Tree-shaking,体积更小,且原生支持 TypeScript。
特性 Vue 2 Vue 3 响应式系统 Object.definePropertyProxy架构 单一源码 模块化架构(Tree-shakable) Composition API ❌ ✅ Fragment ❌ ✅ Suspense 组件 ❌ ✅ 自定义渲染器支持 有限 更灵活 支持 TypeScript ❌(需额外配置) ✅ 原生支持
import { ref, onMounted } from 'vue' ;
export default {
setup ( ) {
const count = ref (0 );
function increment ( ) {
count.value ++;
}
onMounted ( {
. ( );
});
{ count, increment };
}
};
() =>
console
log
'组件挂载'
return
2. 如何在 Vue 3 中创建一个响应式对象? 对于深层嵌套的对象或复杂结构,推荐使用 reactive()。它返回一个代理对象,对属性的修改会自动触发视图更新。
import { reactive } from 'vue' ;
const user = reactive ({
name : 'Alice' ,
age : 25
});
3. ref() 和 reactive() 的区别?
ref() :适用于基本类型(数字、字符串等)或单个值。访问时需要 .value。
reactive() :适用于对象或复杂结构。访问属性时不需要 .value。
import { ref, reactive } from 'vue' ;
const count = ref (0 );
const user = reactive ({ name : 'Bob' });
count.value ++;
user.name = 'Tom' ;
4. Vue 3 中如何监听数据变化? 考察点: watchEffect 与 watch 的差异。
watchEffect :自动追踪依赖并执行副作用,适合一次性初始化逻辑。
watch :手动指定监听的目标,适合需要对比新旧值的场景。
import { ref, watchEffect, watch } from 'vue' ;
const count = ref (0 );
watchEffect (() => {
console .log ('Count changed:' , count.value );
});
watch (count, (newVal, oldVal ) => {
console .log (`从 ${oldVal} 变为 ${newVal} ` );
});
5. Vue 3 的生命周期钩子有哪些?如何使用? 考察点: 生命周期钩子在 setup() 中的导入与使用。
Vue 3 提供了与 Vue 2 类似的生命周期钩子,但必须以 on 开头命名,并从 vue 包中导入。
import { onMounted } from 'vue' ;
export default {
setup ( ) {
onMounted (() => {
console .log ('组件已挂载' );
});
}
};
6. Vue 3 中如何进行父子组件通信? 考察点: Props 传递与 Emit 事件触发。
父组件通过 props 传递数据,子组件通过 emit 触发事件通知父组件。在 <script setup> 中,可以使用 defineProps 和 defineEmits 简化声明。
<script setup>
import { defineProps, defineEmits } from 'vue' ;
const props = defineProps (['title' ]);
const emit = defineEmits (['update' ]);
function handleClick ( ) {
emit ('update' , 'New Value' );
}
</script>
<template >
<button @click ="handleClick" > {{ title }}</button >
</template >
<template >
<Child :title ="msg" @update ="handleUpdate" />
</template >
<script setup >
import Child from './Child.vue' ;
const msg = 'Hello' ;
function handleUpdate (value ) {
console .log ('收到更新:' , value);
}
</script >
7. Vue 3 的 setup() 函数的作用是什么? 考察点: Composition API 入口与逻辑组织。
setup() 是 Vue 3 Composition API 的入口函数。它替代了 Vue 2 中的 data、methods、computed 等选项,允许开发者以函数形式组织逻辑,便于复用和模块化。
export default {
setup ( ) {
const message = ref ('Hello Vue 3' );
function changeMessage ( ) {
message.value = 'Updated!' ;
}
return { message, changeMessage };
}
};
8. Vue 3 中如何实现响应式计算属性? 当需要根据其他响应式状态派生出新值时,使用 computed()。它具有缓存机制,只有依赖项改变时才会重新计算。
import { ref, computed } from 'vue' ;
export default {
setup ( ) {
const firstName = ref ('John' );
const lastName = ref ('Doe' );
const fullName = computed (() => `${firstName.value} ${lastName.value} ` );
return { firstName, lastName, fullName };
}
};
9. provide() 和 inject() 的作用是什么? 用于祖先组件向后代组件注入依赖,避免 props 逐层透传(Prop Drilling)。适合全局配置或主题切换等场景。
import { provide, ref } from 'vue' ;
export default {
setup ( ) {
const theme = ref ('dark' );
provide ('theme' , theme);
return { theme };
}
};
import { inject } from 'vue' ;
export default {
setup ( ) {
const theme = inject ('theme' );
return { theme };
}
};
10. Vue 3 中如何使用插槽(Slot)? 插槽允许父组件向子组件传递内容,增强组件的灵活性。
<template >
<Card >
<template #default > 这是默认插槽内容</template >
<template #header > 这是头部插槽</template >
</Card >
</template >
<template >
<div class ="card" >
<header > <slot name ="header" > </slot > </header >
<main > <slot > </slot > </main >
</div >
</template >
11. Vue 3 中的 Teleport 有什么用途? Teleport 可以将组件模板的一部分渲染到 DOM 树的其他位置,常用于模态框、下拉菜单等需要脱离当前容器层级限制的组件。
<template >
<teleport to ="body" >
<div v-if ="showModal" class ="modal" > 这是一个模态框</div >
</teleport >
</template >
12. Vue 3 中的 Suspense 是什么?怎么用? Suspense 是一个内置组件,用于处理异步依赖。在异步组件加载完成前,显示 fallback 模板。
<template >
<suspense >
<template #default >
<AsyncComponent />
</template >
<template #fallback >
加载中...
</template >
</suspense >
</template >
<script >
import { defineAsyncComponent } from 'vue' ;
const AsyncComponent = defineAsyncComponent (() => import ('./MyComponent.vue' ));
</script >
13. Vue 3 中的 defineProps 和 defineEmits 是什么? 在 <script setup> 中,可以直接使用宏来声明 props 和 emits,无需在 setup 函数中显式返回。
<script setup >
import { defineProps, defineEmits } from 'vue' ;
const props = defineProps (['title' ]);
const emit = defineEmits (['update' ]);
function updateTitle ( ) {
emit ('update' , 'New Title' );
}
</script >
<template >
<h1 > {{ title }}</h1 >
<button @click ="updateTitle" > 更新标题</button >
</template >
14. Vue 3 中如何动态绑定样式? <template >
<div :style ="{ backgroundColor: color }" > {{ text }}</div >
</template >
<script setup >
import { ref } from 'vue' ;
const color = ref ('lightblue' );
const text = ref ('动态样式' );
</script >
15. Vue 3 中如何注册全局组件? 在 createApp 实例上使用 component 方法注册,即可在任何地方直接使用。
import { createApp } from 'vue' ;
import App from './App.vue' ;
import MyButton from './components/MyButton.vue' ;
const app = createApp (App );
app.component ('MyButton' , MyButton );
app.mount ('#app' );
<template >
<my-button label ="提交" />
</template >
16. Vue 3 中如何实现自定义指令? 自定义指令允许直接操作 DOM,常用于高亮、焦点控制等场景。
import { createApp } from 'vue' ;
import App from './App.vue' ;
const app = createApp (App );
app.directive ('highlight' , {
mounted (el ) {
el.style .backgroundColor = '#f0e68c' ;
}
});
app.mount ('#app' );
<template >
<p v-highlight > 这段文字被高亮了</p >
</template >
17. Vue 3 中的 nextTick() 怎么用? 当修改数据后,DOM 更新是异步的。若需立即获取更新后的 DOM,应使用 nextTick()。
import { nextTick } from 'vue' ;
async function updateData ( ) {
this .message = '更新后的内容' ;
await nextTick ();
console .log ('DOM 已更新' );
}
18. Vue 3 中如何实现组件懒加载? 使用 defineAsyncComponent 可以按需加载组件,减少首屏资源消耗。
import { defineAsyncComponent } from 'vue' ;
const AsyncComponent = defineAsyncComponent (() => import ('./components/LazyComponent.vue' ));
export default {
components : { AsyncComponent }
};
19. Vue 3 中的 emitter 是什么?如何使用? Vue 3 移除了 $on 等事件总线方法,推荐引入第三方库如 mitt 来实现全局事件通信。
import mitt from 'mitt' ;
export const emitter = mitt ();
import { emitter } from './eventBus' ;
emitter.emit ('update' , 'Hello' );
import { emitter } from './eventBus' ;
emitter.on ('update' , (msg ) => {
console .log (msg);
});
20. Vue 3 中如何使用 v-model 实现双向绑定? Vue 3 中 v-model 默认绑定 modelValue 属性和 update:modelValue 事件,支持多模型绑定。
<template >
<input :value ="modelValue" @input ="$emit('update:modelValue', $event.target.value)" />
</template >
<script setup >
export default {
props : ['modelValue' ],
emits : ['update:modelValue' ]
};
</script >
总结 以上 20 个问题涵盖了 Vue 3 的核心特性。建议在实际开发中结合项目场景反复练习,特别是 Composition API 的逻辑复用与响应式原理的理解,这往往是区分初级与高级开发者的关键点。
相关免费在线工具 Keycode 信息 查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
Escape 与 Native 编解码 JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
JavaScript / HTML 格式化 使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
JavaScript 压缩与混淆 Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online