常见面试题
字数: 0 字 时长: 0 分钟
简介
整理 Vue3 面试中出现频率最高的一些问题,配合简答和代码示例,方便随时复习。
v-if 和 v-show 的区别
v-if:真正的条件渲染,条件为假时元素直接从 DOM 中移除,有更高的切换开销。v-show:通过 CSS 的display: none控制显隐,元素始终渲染在 DOM 中,有更高的初始渲染开销。
频繁切换用
v-show,条件很少变化用v-if。
computed 和 watch 的区别
computed:计算属性,基于依赖缓存,依赖不变时多次访问只计算一次,必须有返回值。watch:侦听器,监听数据变化后执行副作用(发请求、操作 DOM 等),支持异步。
vue
<script setup>
import { ref, computed, watch } from "vue";
const count = ref(0);
// computed:有缓存,依赖 count
const double = computed(() => count.value * 2);
// watch:数据变化后执行回调
watch(count, (newVal, oldVal) => {
console.log(`从 ${oldVal} 变成 ${newVal}`);
});
</script>另外还有一个 watchEffect:立即执行一次,并自动收集回调中用到的响应式依赖。
v-for 为什么要加 key
key 是 Vue diff 算法中识别节点的标识:
- 有了唯一且稳定的
key,Vue 可以准确复用和移动 DOM 节点,而不是就地复用。 - 不要用
index作为key,列表顺序变化时会导致状态错乱(比如输入框内容串行)。
vue
<template>
<!-- ✅ 使用唯一 id -->
<li v-for="item in list" :key="item.id">{{ item.name }}</li>
</template>nextTick 是干什么的
Vue 更新 DOM 是异步的:数据变化后不会立刻更新视图,而是把更新推入微任务队列批量执行。nextTick 用于在 DOM 更新完成后执行回调。
js
import { nextTick } from "vue";
count.value++;
// 此刻 DOM 还没更新
await nextTick();
// 这里才能拿到更新后的 DOMkeep-alive 的作用
keep-alive 可以缓存组件实例,切换时不销毁组件,避免重复渲染和状态丢失,常用于 tab 切换、列表页跳转详情页后返回。
vue
<template>
<keep-alive :include="['ListPage']" :max="10">
<component :is="currentView" />
</keep-alive>
</template>被缓存的组件会多出两个生命周期钩子:onActivated(激活)和 onDeactivated(失活)。
Vue2 和 Vue3 的区别
面试必考题,主要回答这几点:
- 响应式原理:
Object.defineProperty→Proxy。 - API 风格:选项式 API → 组合式 API(逻辑复用更灵活)。
- 生命周期:
beforeCreate/created被setup替代,钩子加on前缀。 - 模板:支持多个根节点(Fragment)。
- 性能:虚拟 DOM 重写(静态提升、补丁标记)、Tree-shaking 支持更好、打包体积更小。
- TypeScript:Vue3 源码用 TS 重写,类型支持更完善。
Vue2 中 data 为什么必须是函数
组件会被复用多次,如果 data 是对象,所有实例会共享同一个对象的引用,一个实例修改数据会影响其他实例。写成函数后,每次创建实例都会调用函数返回一份全新的数据对象,互不影响。
Vue 是单向数据流还是双向绑定
两者都有,但要分清场景:
- 单向数据流:props 只能从父流向子,子组件不能直接修改 props。
- 双向绑定:
v-model是语法糖,本质是:value+@input的单向数据流 + 事件回传,并不是真正的双向。
最后更新于: 2026/8/5 15:00:00