以下是针对 Vue 2 的面试题,总共100道,涵盖了基础概念、核心特性、组件、路由、状态管理等方面。
目录
18. Vue 中如何实现计算属性的 setter 和 getter?
21. Vue 的 v-if 和 v-show 有什么区别?
22. Vue 的 $attrs 和 $listeners 是什么?
28. Vue 的 beforeDestroy 生命周期钩子有什么用?
31. 如何使用 Vue 组件的 slots 传递动态内容?
36. Vue 组件中的 与listeners 有什么关系?
40. Vue 组件的 mounted 钩子与 created 钩子的区别?
50. Vue 的 v-model 能与哪些表单元素一同使用?
53. Vue 状态管理中 mapState 的使用是什么?
58. Vue 的 provide/inject 和 Props 之间有什么区别?
65. Vue 组件的 activated 和 deactivated 生命周期钩子的作用是什么?
70. Vue 中的 v-model 如何与复选框和单选框结合使用?
72. Vue.js 中的 computed 与 methods 的区别?
75. Vue 的 computed 属性是否会响应式更新?
77. Vue 中 beforeRouteEnter 导航守卫的作用?
80. Vue 组件中如何使用 v-bind 绑定多个属性?
84. Vue中如何使用 v-if 与 v-else 配合使用?
85. Vue.js 中,组件的 name 属性的作用是什么?
94. Vue 中如何使用 beforeMount 生命周期钩子?
97. 在 Vue 中如何使用 mounted 和 updated 生命周期?
1. 什么是 Vue.js?
答: Vue.js 是一款用于构建用户界面的渐进式 JavaScript 框架。其核心库专注于视图层,采用 MVVM(Model-View-ViewModel)模式,简单灵活,便于开发单页应用。
2. Vue 的核心特性有哪些?
答:
- 响应式数据绑定:通过观察者模式,实现数据与视图的双向绑定。
- 组件化:提供了可以复用的组件结构,便于管理和维护代码。
- 指令:提供了如
v-bind
,v-if
,v-for
等指令来操作 DOM。 - 单文件组件:支持
.vue
格式的文件,将模板、脚本和样式分离,便于开发。
3. Vue 的实例是如何创建的?
答: Vue 的实例通过 new Vue()
创建。可以传递一个选项对象进行配置。
例子:
const app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
});
4. 数据是如何响应式的?
答: 在 Vue 2 中,数据的响应式是通过一种称为“观察者模式”的设计模式来实现的。Vue 使用 Object.defineProperty()
方法来劫持(“proxy”)对象的属性,并通过 getter 和 setter 来跟踪属性的变化,从而实现数据和视图的自动同步。
5. Vue 中的计算属性是什么?
答: 计算属性是基于它们的依赖进行缓存的属性。当依赖的值没有发生改变时,计算属性会被缓存,避免不必要的重复计算。
例子:
new Vue({
el: '#app',
data: {
a: 1,
b: 2
},
computed: {
sum() {
return this.a + this.b;
}
}
});
6. Vue 中的侦听器(watch)是什么?
答: 侦听器是用于观察 Vue 实例上的数据变动并在变化时执行异步或开销较大的操作。相比计算属性,侦听器更适合处理复杂逻辑。
例子:
new Vue({
el: '#app',
data: {
a: 1
},
watch: {
a(newVal, oldVal) {
console.log(`a changed from ${oldVal} to ${newVal}`);
}
}
});
7. Vue 中的指令有哪些?
答:
- v-bind:动态绑定属性。
- v-model:用于表单元素的双向数据绑定。
- v-if、v-else-if、v-else:条件渲染。
- v-for:列表渲染。
- v-show:控制元素的显示与隐藏。
8. Vue 的生命周期是什么?
答: Vue 实例在创建的过程中会经历一系列的生命周期钩子,从创建到销毁。常用的生命周期钩子包括:
created
:实例被创建后调用,数据已经设置。mounted
:DOM 挂载后调用,适合获取 DOM 元素。updated
:数据更新后调用,适合响应数据变化。destroyed
:实例销毁后调用,适合释放资源。
9. Vue.js 是如何处理事件的?
答: Vue 对事件的处理是通过 v-on
指令进行的,可以绑定用户输入或 DOM 事件。
例子:
<button v-on:click="doSomething">Click me</button>
methods: {
doSomething() {
alert('Button clicked!');
}
}
10. Vue 组件是如何定义的?
答: Vue 组件是通过 Vue.extend 方法或者简单的对象字面量创建的。
例子:
Vue.component('my-component', {
template: '<div>A custom component!</div>'
});
11. Vue 的组件之间如何传值?
答: 组件之间的值传递可以通过 props
和事件机制来完成。父组件通过 props
传递数据给子组件,子组件通过 $emit
发送事件给父组件。
例子:
<!-- 父组件 -->
<child-component :prop-value="data" @child-event="handleChildEvent"></child-component>
12. 什么是 Vue 的插槽(slots)?
答: 插槽是 Vue 组件之间的内容分发机制。父组件可以将内容插入到子组件的特定位置上。
例子:
<child-component>
<p>This will be rendered in the child component!</p>
</child-component>
Vue.component('child-component', {
template: '<div><slot></slot></div>'
});
13. Vue 的过滤器是什么?
答: 过滤器是用于格式化文本的简单函数。可以应用于插值和 v-bind
表达式。
例子:
Vue.filter('capitalize', function (value) {
if (!value) return '';
return value.charAt(0).toUpperCase() + value.slice(1);
});
// 使用过滤器
{{ message | capitalize }}
14. Vue 的过渡动画如何实现?
答: Vue 提供了 <transition>
组件来管理元素的过渡动画。可以通过 CSS 或 JavaScript 钩子来实现动画效果。
例子:
<transition>
<div v-if="show">Show me</div>
</transition>
.fade-enter-active, .fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter, .fade-leave-to {
opacity: 0;
}
15. Vuex 的核心概念有哪些?
答: Vuex 是 Vue.js 的状态管理库,其核心概念包括:
- State:单一状态树,用于存储应用的状态。
- Getters:计算属性,用于从状态中派生数据。
- Mutations:同步改变状态的方法。
- Actions:可以包含异步操作的事件,调用 mutations 进行状态改变。
- Modules:将 store 分割成模块,使其更易维护。
16. Vue 的异步更新队列是什么?
答: Vue 在更新 DOM 时是异步的,所有的数据更新会进入一个队列,并在下一个事件循环中批量处理,这样可以提高性能。
17. Vue 中 v-model
的工作原理是什么?
答: v-model
指令用于在表单控件元素上创建双向绑定。对于输入框,它会把输入框的值与 Vue 实例中的数据进行绑定,并在用户输入时自动更新数据。
例子:
<input v-model="message">
18. Vue 中如何实现计算属性的 setter 和 getter?
答: 通过在计算属性中定义 get
和 set
方法来实现。
例子:
computed: {
fullName: {
get() {
return `${this.firstName} ${this.lastName}`;
},
set(value) {
const names = value.split(' ');
this.firstName = names[0];
this.lastName = names[1];
}
}
}
19. Vue 如何避免事件冒泡?
答: 在事件处理函数中使用 event.stopPropagation()
方法可以阻止事件的冒泡行为。
例子:
methods: {
handleClick(event) {
event.stopPropagation();
// 其他逻辑
}
}
20. Vue 中如何使用动态组件?
答: 可以使用 <component>
标签来创建动态组件,使用 is
属性指定要渲染的组件。
例子:
<component :is="currentComponent"></component>
data() {
return {
currentComponent: 'componentA'
};
}
21. Vue 的 v-if
和 v-show
有什么区别?
答:
v-if
:条件渲染,只有条件为真时才会渲染该元素,切换条件会导致 DOM 的增删。v-show
:仅切换元素的 CSSdisplay
属性,元素始终会被渲染,但在条件为假时会被隐藏。
例子:
<div v-if="isVisible">Visible when true</div>
<div v-show="isVisible">Always rendered but shown/hidden</div>
22. Vue 的 $attrs
和 $listeners
是什么?
答:
$attrs
:包含了父组件传入非 prop 的属性,适用于不想在子组件中声明的属性。$listeners
:包含了父组件传入的所有事件监听器。
例子:
<child-component v-bind="$attrs" v-on="$listeners"></child-component>
23. 如何在 Vue 中使用外部库(如 jQuery)?
答: 在 Vue 中可以直接在组件的钩子中引用外部库。通常,在 mounted
中使用,因为此时 DOM 已经渲染完成。
例子:
mounted() {
$(this.$el).fadeIn();
}
24. Vue Router 是什么?
答: Vue Router 是 Vue.js 官方的路由管理器,用于管理多页面应用的路由,支持历史模式和 hash 模式。
25. Vue Router 中的路由懒加载是什么?
答: 路由懒加载是按需加载路由组件,通常结合 Webpack 的代码分割实现。
例子:
const User = () => import('./components/User.vue');
const routes = [
{ path: '/user', component: User }
];
26. Vue 中如何处理表单验证?
答: 可以使用第三方库如 VeeValidate 或自定义验证逻辑,在表单输入的 @input
事件中进行验证。
例子:
methods: {
validate() {
if (this.inputValue === '') {
this.error = 'Input cannot be empty';
}
}
}
27. Vue 中如何使用自定义指令?
答: 自定义指令是使用 Vue.directive
创建的,主要用于直接操作 DOM。
例子:
Vue.directive('focus', {
// 当被绑定的元素插入到 DOM 中时……
inserted: function (el) {
el.focus();
}
});
28. Vue 的 beforeDestroy
生命周期钩子有什么用?
答: beforeDestroy
钩子在实例销毁之前调用,可以在这里释放定时器和事件监听器等资源。
例子:
beforeDestroy() {
clearInterval(this.timer);
}
29. 如何使 Vue 组件具有全局事件监听能力?
答: 使用 Event Bus
解决全局事件传递,可以创建一个 Vue 实例作为事件总线。
例子:
// eventBus.js
import Vue from 'vue';
export const EventBus = new Vue();
30. 在 Vue 中使用 watch
侦听多个数据源?
答: 通过将多个数据源名称放入数组中监视实现。
例子:
watch: {
options: {
handler(newVal, oldVal) {
console.log(newVal);
},
immediate: true
}
}
31. 如何使用 Vue 组件的 slots 传递动态内容?
答: 动态插槽可以使用 v-slot
指令。
例子:
<template #header>
<h1>Dynamic Header</h1>
</template>
<VueComponent>
<template v-slot:header>
<h1>Dynamic Content</h1>
</template>
</VueComponent>
32. Vue 中如何实现组件的单例模式?
答: 可以通过 Vuex 作为状态管理工具,并限制创建新组件实例的条件。
例子:
// 在 Vuex 中存储实例状态
33. Vue 中如何创建递归组件?
答: 可以通过组件内部去引用自身的方式实现递归。
例子:
Vue.component('tree-view', {
props: ['data'],
template: `
<ul>
<li v-for="node in data">
{{ node.name }}
<tree-view v-if="node.children" :data="node.children"></tree-view>
</li>
</ul>
`
});
34. Vue 的 v-once
指令有什么用?
答: v-once
用于指示 Vue 仅渲染一次元素和组件,后续的更新将不会影响它。
例子:
<div v-once>This will never change: {{ message }}</div>
35. Vue 中如何使用 nextTick
?
答: nextTick
用于在下一个 DOM 更新循环中执行延迟回调,可以在更新完成后获取更新后的 DOM 状态。
例子:
this.message = 'Hello';
this.$nextTick(() => {
console.log(this.$el.textContent); // Updated message
});
36. Vue 组件中的 与listeners 有什么关系?
答: $emit
用于子组件向父组件发送事件,而 $listeners
用于接收父组件传递的事件监听。
37. Vue 组件如何实现 CSS Scoped 样式?
答: 通过在 <style>
标签上添加 scoped
属性实现样式仅作用于当前组件。
例子:
<style scoped>
h1 {
color: red;
}
</style>
38. Vue 组件的 key
属性有什么用?
答: key
是用于标识每个组件的唯一性,Vue 利用 key
进行高效的 DOM 管理和重渲染。
例子:
<component v-for="item in items" :key="item.id" :is="item.type"></component>
39. 在 Vue.js 中如何处理跨域请求?
答: 可以通过代理解决跨域问题,或者在服务器设置 CORS(跨域资源共享)。
40. Vue 组件的 mounted
钩子与 created
钩子的区别?
答:
created
钩子在实例创建完成后立即调用,适合进行数据初始化。mounted
钩子在 DOM 挂载后调用,适合与 DOM 进行交互。
41. Vue 的 $destroy
方法有什么作用?
答: $destroy
方法用于手动销毁 Vue 实例,清理相关的事件监听和所有子组件。
42. 组件中如何使用 v-for
渲染列表?
答: 使用 v-for
指令迭代数组或对象。
例子:
<ul>
<li v-for="item in items" :key="item.id">{{ item.name }}</li>
</ul>
43. 使用 Vue 创建的应用如何进行代码分割?
答: 利用 Vue Router 的懒加载特性(如前面第25条)实现按需加载。
44. Vue 数据更新时的性能优化策略有哪些?
答:
- 使用计算属性代替方法。
- 利用
v-if
和v-show
优化条件渲染。 - 使用
key
提升列表渲染的性能。
45. Vue 的 v-bind
指令有什么用?
答: v-bind
用于动态绑定一个或多个属性到某个元素。
例子:
<img v-bind:src="imageSrc">
46. Vue 中如何进行 A/B 测试?
答: 可以通过动态组件和切换可选项来完成 A/B 测试。
<component :is="isVariantA ? 'VariantA' : 'VariantB'"></component>
47. 如何在 Vue 中调用 API?
答: 使用 axios
或 fetch
进行 API 请求,通常在 mounted
钩子中执行。
例子:
mounted() {
axios.get('/api/data').then(response => {
this.data = response.data;
});
}
48. Vue 中如何设置动态 Class?
答: 使用 v-bind:class
来动态绑定 class。
例子:
<div v-bind:class="{ active: isActive }"></div>
49. 在 Vue 中如何处理全局的过滤器?
答: 通过 Vue.filter
定义全局过滤器。
例子:
Vue.filter('currency', function (value) {
return `$${value.toFixed(2)}`;
});
50. Vue 的 v-model
能与哪些表单元素一同使用?
答: v-model
可以与 <input>
、<textarea>
和 <select>
标签一起使用。
51. Vue 中如何实现组件的插槽传递数据?
答: 使用 slot-scope
进行插槽的数据传递。
例子:
<my-component>
<template v-slot:default="slotProps">
{{ slotProps.text }}
</template>
</my-component>
52. 怎么解决 Vue 组件的命名冲突?
答: 使用模块化的方式(如命名空间)对组件进行分类,避免命名冲突。
53. Vue 状态管理中 mapState
的使用是什么?
答: mapState
是 Vuex 提供的一个辅助函数,用于将 state 映射到组件的计算属性上。
例子:
computed: {
...mapState(['user', 'posts'])
}
54. Vue 中的 v-pre
指令的作用是什么?
答: v-pre
用于跳过这个元素及其子元素的编译过程,适用于显示原始内容。
例子:
<div v-pre>{{ rawHtml }}</div> <!-- 输出原始文本,未编译 -->
55. Vue 的 $refs
属性有什么作用?
答: $refs
属性用于访问 DOM 元素或组件实例,可以通过 ref
指令定义。
例子:
<input ref="myInput">
this.$refs.myInput.focus();
56. Vue 中的 v-cloak
指令有什么用?
答: v-cloak
指令用于在 Vue 实例创建过程中,防止未编译的插值渲染。
57. 在 Vue 中如何捕获全局错误?
答: 使用 Vue.config.errorHandler
配置全局错误处理函数。
例子:
Vue.config.errorHandler = function (err, vm, info) {
console.error(err);
};
58. Vue 的 provide/inject
和 Props 之间有什么区别?
答:
provide/inject
用于跨层级的组件传值,而 Props 是父子组件直接传值。provide/inject
可以在任意层级进行数据访问。
59. 怎样在 Vue 中实现服务端渲染(SSR)?
答: 通过 Vue 的 SSR 插件和 Node.js 进行服务端渲染。常用工具包括 vue-server-renderer
。
60. 在 Vue 中如何调试应用?
答: 可以使用 Vue Devtools 浏览器插件,便于查看组件、状态和事件。
61. Vue 的 v-on
指令有哪些常用修饰符?
答:
.stop
:调用event.stopPropagation()
。.prevent
:调用event.preventDefault()
。.self
:仅当事件在该元素本身触发时才触发事件处理器。
62. 如何在 Vue 中执行条件渲染?
答: 使用 v-if
或 v-show
指令实现条件渲染。
例子:
<div v-if="isLoggedIn">Welcome back!</div>
63. Vue 如何处理组件间的通信问题?
答: 可通过 Props、事件总线、Vuex、provide/inject 等多种方法处理组件间的通信。
64. Vue 的 v-for
如何设置唯一的 key
?
答: 在使用 v-for
时,通过 :key
属性将该元素的唯一标识符绑定到 DOM 元素上。
例子:
<li v-for="item in items" :key="item.id">{{ item.name }}</li>
65. Vue 组件的 activated
和 deactivated
生命周期钩子的作用是什么?
答: 这两个钩子用于处理 keep-alive
组件的激活和停用状态。
66. 如何优雅地进行 Vue 组件的异步请求?
答: 在组件的 mounted
钩子中进行异步请求,并在请求完成后更新数据。
67. Vue 组件中如何使用 this
?
答: 在 Vue 组件的实例方法、生命周期钩子、计算属性等上下文中使用 this
访问组件实例。
68. 可以通过什么方式保护 Vue 的路由?
答: 使用导航守卫(beforeEach、beforeEnter)来验证用户的授权状态。
例子:
router.beforeEach((to, from, next) => {
if (to.meta.requiresAuth && !isAuthenticated()) {
next('/login');
} else {
next();
}
});
69. 如何在 Vue 中操作 DOM?
答: 可以使用 ref
来引用 DOM 元素,在方法中通过 this.$refs
访问。
例子:
<template>
<div ref="myDiv">Hello</div>
</template>
<script>
export default {
mounted() {
console.log(this.$refs.myDiv.textContent);
}
};
</script>
70. Vue 中的 v-model
如何与复选框和单选框结合使用?
答: v-model
可以与复选框和单选框结合使用,支持数组形式的多选。
例子:
<input type="checkbox" v-model="checkedItems" value="A">
<input type="checkbox" v-model="checkedItems" value="B">
71. Vue 的 key 值的作用是?
答: key 的主要作用是帮助 Vue 识别哪些元素发生了变化、添加或删除,提高渲染性能。
72. Vue.js 中的 computed
与 methods
的区别?
答:
computed
属性是基于它们的依赖进行缓存的,当依赖未发生改变时,不会重新计算。methods
每次调用都会执行,适合需要执行复杂逻辑的场景。
73. 如何在 Vue 中合并对象?
答: 可以使用 Object.assign() 或 Vue.set() 来合并对象。
例子:
Object.assign(this.obj1, this.obj2);
74. 请简要描述 Vue 的响应式原理?
答: Vue 使用 Object.defineProperty() 将对象属性转换为 getter 和 setter,以实现数据变化时视图更新。
75. Vue 的 computed 属性是否会响应式更新?
答: 是的,computed 属性会响应式更新,当依赖的数据发生变化时,会针对此 computed 属性重新计算值。
76. Vue 如何处理动态组件?
答: 动态组件通过 component
标签和 is
属性实现,允许在运行时指定渲染的组件。
例子:
<component :is="currentComponent"></component>
77. Vue 中 beforeRouteEnter
导航守卫的作用?
答: beforeRouteEnter
在路由进入之前调用,适合获取路由参数或异步加载数据。
78. Vue 中 v-slot
的使用场景是什么?
答: v-slot
用于组件插槽的命名和具名插槽,从而可以更灵活地传递内容和数据。
例子:
<template v-slot:header>
<h1>Header Content</h1>
</template>
79. Vue 中的 $http 属性使用场景?
答: $http 属性用于跨域请求或 AJAX 请求,依赖于外部库如 Axios 进行处理。
80. Vue 组件中如何使用 v-bind
绑定多个属性?
答: 通过使用 v-bind
和对象语法一次性绑定多个属性。
例子:
<div v-bind="{ id: someId, class: someClass }"></div>
81. Vue 中如何在多个组件间共享数据?
答: 可以使用 Vuex 作为状态管理工具、Event Bus 或者通过 props 进行数据传递和共享。
82. Vue 中如何以编程方式导航?
答: 通过 this.$router.push()
和 this.$router.replace()
导航到指定路由。
83. 如何在 Vue 中确定组件的加载状态?
答: 可以通过 v-if
和数据属性来判断组件的加载状态。
例子:
<div v-if="isLoading">Loading...</div>
84. Vue中如何使用 v-if
与 v-else
配合使用?
答: 通过在元素上使用 v-if
和紧跟着的 v-else
或者 v-else-if
指令进行条件渲染。
例子:
<div v-if="isTrue">True</div>
<div v-else>False</div>
85. Vue.js 中,组件的 name
属性的作用是什么?
答: name
属性用于定义组件的名称,有助于调试和递归组件。
86. Vue 项目的热重载是如何工作的?
答: 通过 Webpack 中的热模块替换功能实现,即在运行时更新模块而无需刷新页面。
87. Vue Router 模拟的导航守卫有什么作用?
答: 导航守卫用于在路由进入、离开和更新时执行逻辑,例如权限验证、异步数据获取等。
88. 在 Vue 中如何自定义事件?
答: 通过 $emit
方法在子组件中触发自定义事件,并在父组件中进行监听。
89. 如何在 Vue 中 divide 组件?
答: 可以使用 Vue.component
进行组件的定义和注册,或使用单文件组件进行结构化管理。
90. Vue 的响应式原理如何影响性能?
答: 通过观察数据变化并触发更新,当数据频繁变更时,会对性能带来一定的负担,可以通过合理选择使用计算属性和避免不必要的 computed 和 watch 来优化性能。
91. Vue 的 v-cloak
是什么?
答: v-cloak
用于防止 Vue 实例创建过程中的内容闪烁,通常与 CSS 一起使用。
92. Vue 组件的 $destroy
方法有什么用途?
答: $destroy
用户手动销毁 Vue 实例,释放占用的内存和事件监听。
93. 在 Vue 中如何自定义组件事件?
答: this.$emit()
方法用来创建自定义组件事件,并传递参数。
94. Vue 中如何使用 beforeMount
生命周期钩子?
答: 组件在挂载之前调用 beforeMount
,适用于初始化操作。
95. Vue 应用中如何处理 SEO 问题?
答: 使用服务器渲染(SSR)或适配 Google 的爬虫策略优化 Vue 应用以支持 SEO。
96. Vue 的 和router 是什么?
答:
$route
是当前路由信息对象,包含路由的参数和信息。$router
是 Vue Router 的实例,提供导航的方法。
97. 在 Vue 中如何使用 mounted
和 updated
生命周期?
答: mounted
在组件挂载到 DOM 后调用,updated
在组件响应数据更新后调用,用于处理 DOM 变化时的逻辑。
98. Vue 中如何实现路由的懒加载?
答: 借助 Webpack 的动态导入特性进行路由懒加载。
例子:
const Home = () => import('./components/Home.vue');
99. 如何在 Vue 组件中使用样式 scoped?
答: 在 <style>
标签中添加 scoped
属性实现样式的局部性。
例子:
<style scoped>
p {
color: red;
}
</style>
100. Vue 复用组件的方法是什么?
答: 可以利用 Vue 的插槽、Mixin、Vuex 的 Store 或者高阶组件实现组件的复用。