20道Vue.js常见面试题
以下是20道常见的 Vue.js 面试题及其答案,涵盖基础、生命周期、指令、组件通信等内容:
1. 什么是Vue.js?它的主要特点是什么?
答案:
Vue.js 是一个用于构建用户界面的渐进式 JavaScript 框架,适合开发单页应用(SPA)。
主要特点包括:
- 数据驱动视图(MVVM 模式)
- 双向绑定(基于
v-model
) - 组件化开发
- 指令(如
v-for
、v-if
) - 易于集成和渐进式采用
2. Vue 的生命周期有哪些?
答案:
Vue 实例的生命周期主要包括以下阶段:
- 创建阶段:
beforeCreate
、created
- 挂载阶段:
beforeMount
、mounted
- 更新阶段:
beforeUpdate
、updated
- 销毁阶段:
beforeUnmount
(Vue 3)、unmounted
3. 什么是Vue中的指令?常用的指令有哪些?
答案:
指令是用于操作 DOM 的特殊标记。Vue 提供了一些内置指令,常用指令包括:
v-bind
:绑定属性v-model
:双向绑定v-for
:列表渲染v-if
/v-else
/v-else-if
:条件渲染v-on
:事件绑定v-show
:控制元素显示/隐藏
示例:
<p v-if="show">Hello Vue!</p>
4. Vue的双向绑定是如何实现的?
答案:
Vue 的双向绑定是通过 数据劫持(Object.defineProperty
或 Proxy
)和 发布-订阅模式 实现的:
- 通过
getter
和setter
监听数据变化。 - 数据变化时,通知依赖更新视图。
- 视图更新通过事件(如
input
)同步数据。
5. Vue中的计算属性(computed)和方法(methods)有什么区别?
答案:
- 计算属性(computed):基于依赖缓存结果,只有依赖发生变化时才重新计算。
- 方法(methods):每次调用都会执行。
示例:
computed: {
fullName() {
return this.firstName + ' ' + this.lastName; // 依赖 firstName 和 lastName
}
}
methods: {
getFullName() {
return this.firstName + ' ' + this.lastName; // 每次调用都会执行
}
}
6. 组件之间如何通信?
答案:
-
父子组件通信:
- 父传子:通过
props
- 子传父:通过
$emit
- 父传子:通过
-
兄弟组件通信:
- 使用事件总线(Vue 2)
- 使用状态管理(Vuex 或 Pinia)
-
跨层级通信:
- 使用
provide
和inject
(Vue 3) - 使用全局事件总线或 Vuex
- 使用
7. 什么是Vue中的单向数据流?
答案:
单向数据流指的是组件的数据流动是单向的:
- 父组件通过
props
向子组件传递数据。 - 子组件不能直接修改父组件的数据,而是通过事件通知父组件。
8. Vue中的v-if
和v-show
有什么区别?
答案:
v-if
:按条件动态添加或删除元素,会销毁或重新渲染。v-show
:仅控制元素的 CSSdisplay
属性,不会销毁 DOM 节点。
9. 什么是Vue的虚拟DOM?
答案:
虚拟 DOM 是用 JavaScript 对象表示真实 DOM 的一种抽象。当数据变化时,Vue 会通过 Diff 算法对比新旧虚拟 DOM 的差异,并高效更新真实 DOM。
10. Vue组件中的data
为什么必须是一个函数?
答案:
在组件中,data
必须是一个函数以确保每个组件实例都有自己的独立数据,而不会共享引用数据(防止数据污染)。
11. 如何在Vue中监听属性的变化?
答案: 可以使用 watch
选项监听数据的变化:
watch: {
count(newVal, oldVal) {
console.log('Count changed from', oldVal, 'to', newVal);
}
}
12. 什么是Vuex
?它有哪些核心概念?
答案:
Vuex 是 Vue 的状态管理工具,主要用于跨组件共享状态。
核心概念:
- State:存储状态
- Getter:计算衍生状态
- Mutation:同步修改状态
- Action:异步操作
- Module:模块化管理状态
13. Vue的路由是如何实现的?
答案:
Vue 路由由 vue-router
实现,它基于 Hash 模式(#
)或 History 模式实现客户端路由切换。
示例:
const routes = [
{ path: '/home', component: Home },
{ path: '/about', component: About }
];
const router = new VueRouter({ routes });
new Vue({
router
}).$mount('#app');
14. 如何优化Vue的性能?
答案:
- 合理使用
v-if
和v-show
- 按需加载组件(路由懒加载)
- 使用虚拟滚动列表
- 使用
key
提高列表渲染性能 - 避免深层数据绑定
- 生产环境启用
Vue.config.productionTip = false
15. 什么是插槽(slot)?有哪些类型?
答案:
插槽用于分发内容,主要有以下类型:
- 默认插槽:
<slot></slot>
- 具名插槽:
<slot name="header"></slot>
- 作用域插槽:
<slot :user="user"></slot>
16. Vue3中Composition API的核心是什么?
答案:
Composition API 提供了更灵活的逻辑复用方式,核心包括:
setup
函数:组件逻辑的入口ref
和reactive
:响应式数据computed
:计算属性watch
和watchEffect
:监听数据
示例:
import { ref } from 'vue';
export default {
setup() {
const count = ref(0);
const increment = () => count.value++;
return { count, increment };
}
};
17. Vue中的$nextTick
是什么?
答案:$nextTick
用于在 DOM 更新完成后执行回调函数。
示例:
this.count++;
this.$nextTick(() => {
console.log('DOM updated');
});
18. Vue3中如何创建全局状态管理?
答案:
Vue3 推荐使用 Pinia 替代 Vuex:
import { defineStore } from 'pinia';
export const useStore = defineStore('main', {
state: () => ({ count: 0 }),
actions: {
increment() {
this.count++;
}
}
});
19. Vue的动态组件是什么?
答案:
动态组件允许根据变量动态切换组件,使用 <component>
实现:
<component :is="currentComponent"></component>
20. 什么是Vue中的混入(mixins)?
答案:
混入(Mixins)是一种复用组件逻辑的技术,将可复用逻辑定义在 mixin 对象中,然后混入到组件中:
const myMixin = {
data() {
return { message: 'Hello' };
}
};
export default {
mixins: [myMixin]
};