汇总了一些相对比较新的高频、重点面试题,包含了些热门技术和知识点。回顾之前发的博文知识点,帮助大家进行知识点复习。祝大家早日能够找到理想的工作。
1、v-show和v-if的区别
- v-show是通过CSS的display来控制隐藏或显示。
- v-if是真正的渲染和销毁,而不是隐藏和显示。
- 如果是频繁切换显示则使用v-show,否则用v-if
2、为何在v-for中用key
- 首先必须用key,且key值不能是index和random
- diff算法中通过tag和key来判断,是否是相同的节点
- 当提供了key时,可以高效识别节点身份,避免不必要的DOM操作。
3、描述Vue组件生命周期(考虑父子组件)
Vue组件生命周期是:created(创建阶段)、mounted(渲染阶段)、updated(更新阶段)、destoryed(销毁阶段) 对于父子组件,它们的生命周期函数调用顺序是父created->子create->子mounted->父mounted->子updated->父updated->子destoryed->父destoryed 也就是说create函数是子组件会在父组件之后调用,mounted和updated函数是子组件优先父组件调用,而在子组件销毁之前,父组件的生命周期函数已经全部执行完毕。
4、Vue组件如何通讯(常见)
- 父子组件可以用props和this.$emit
- 自定义事件 event.off $emit
- vuex
5、描述组件渲染过程和更新过程
vue组件渲染过程包括:
(1)解析模版:Vue会将组件的模版解析成一个抽象语法树(AST),这个AST描述了模版的结构和指令等信息。
(2)创建虚拟DOM:根据AST,Vue会创建一个虚拟DOM,它是一个轻量级的Javascript对象,描述了组件的结构和属性等信息。
(3)生成真实DOM:Vue会将虚拟DOM转换成真实DOM,并插入页面中。
(4)挂载组件:组件被挂载到页面后,Vue会调用组件的生命周期函数,执行一些初始化操作。
Vue组件更新过程包括:
(1)数据更新:当组件的数据发生变化时,Vue会自动触发数据更新。
(2)重新渲染虚拟DOM:Vue会根据数据变化,重新生成虚拟DOM。
(3)更新真实DOM:Vue会将新生成的虚拟DOM与旧的虚拟DOM进行比较,找出需要更新的部分,并将其更新到真实DOM中。
(4)调用生命周期函数:更新完成后,Vue会调用组件的生命周期函数,执行一些更新后的操作。
6、双向数据绑定v-model的真实原理
Vue中的双向数据绑定实际上是一个语法糖,它是基于Vue的单项数据绑定实现的。单向数据绑定是通过数据劫持和发布-订阅模式实现的。当一个组件的数据发生变化时,Vue会自动更新相关的DOM。
具体实现原理是:
- 对于表单元素,Vue会监听其input或change事件,当元素的值发生变化时,会触发Vue的更新机制。
- 在组件的渲染过程中,Vue会为表单元素绑定一个value属性,这个属性是有数据驱动,当数据发生变化时,value数据的值也会相应的更新。
- 当用户修改表单元素的值时,Vue会将修改后的值赋给对应的数据属性,从而实现数据的更新。
7、对MVVM的理解
在Vue中,MVVM代表的是Model-View-ViewModel模式,它是一种前端架构模式,用于将UI逻辑与业务逻辑分离。View代表的是用户界面,ViewModel是View的抽离,Model是数据层。
MVVM模式是通过数据绑定和组件化实现的。数据绑定是指Vue将数据和DOM元素绑定在一起,当数据发生变化时,DOM元素会自动更新。组件化是指将UI界面拆分成独立的组件,每个组件都有自己的逻辑和状态,可以复用和组合。
8、computed有何特点
- 计算属性,依赖缓存,data不变不会重新计算
- computed的值是只读的,提高性能
9、ajax请求应该放在哪个生命周期
ajax请求通常应该放在mounted函数中。mounted是Vue实例挂载到DOM元素完成之后调用的。这个时候DOM已经渲染完成了,可以进行DOM操作了,这个时候就可以ajax请求数据了。
如果将ajax请求放在create或beforeMount中,可能会出现DOM还未渲染完成,这样会导致请求返回的数据无法正确渲染到页面上。
如果将ajax请求放在updated中,可能会造成无限循环的问题。因为ajax请求会导致数据发生变化,从而触发updated函数调用,而updated函数又会重新ajax请求,这样就会陷入死循环。
10、如何将组件所有props传递给子组件
在Vue中,可以使用v-bind指令将组件的所有props传递给子组件。具体来说,可以使用以下方式:
<template>
<child-component v-bind="$props"></child-component>
</template>
在上面的代码中,我们使用了v-bind指令将组件的所有props传递给了子组件child-component。这样,在子组件中就可以直接使用这些props了。
需要注意的是,如果你使用了inheritAttrs选项将父组件的属性绑定到子组件上,那么你需要在子组件中使用$attrs来访问这些属性。例如:
<template>
<child-component v-bind="$attrs"></child-component>
</template>
在上面的代码中,我们使用了$attrs来访问父组件的属性,并将它们传递给了子组件child-component。
11、如何自己实现v-model
可以通过以下步骤:
-
在组件中定义一个value属性和一个input事件。
-
在组件的模板中,将value属性绑定到表单控件的value属性上,并监听input事件,当表单控件的值发生变化时,触发input事件并将新的值作为参数传递出去。
-
在父组件中使用自定义的v-model时,将组件的value属性绑定到父组件的数据上,并监听input事件,当组件的值发生变化时,触发input事件并将新的值作为参数传递给父组件。
下面是一个简单的例子:
<!-- 自定义组件 -->
<template>
<input :value="value" @input="handleInput">
</template>
<script>
export default {
props: {
value: String
},
methods: {
handleInput(event) {
this.$emit('input', event.target.value);
}
}
}
</script>
<!-- 父组件 -->
<template>
<div>
<my-input v-model="message"></my-input>
<p>{{ message }}</p>
</div>
</template>
<script>
import MyInput from './MyInput.vue';
export default {
components: { MyInput },
data() {
return {
message: ''
}
}
}
</script>
在上面的例子中,自定义组件MyInput定义了一个value属性和一个input事件,并将value属性绑定到表单控件的value属性上,并监听input事件,当表单控件的值发生变化时,触发input事件并将新的值作为参数传递出去。在父组件中,使用自定义的v-model时,将组件的value属性绑定到父组件的数据message上,并监听input事件,当组件的值发生变化时,触发input事件并将新的值作为参数传递给父组件,从而实现了双向绑定。
12、多个组件有相同的逻辑,如何抽离
可以通过mixin来抽离多个组件中的相同的逻辑。如果组件和mixin都定义了相同的选项,则优先使用mixin的。如果存在多个mixin被调用,则后面的mixin对象会覆盖前面的mixin对象中的选项。
13、何时要使用异步组件
通常情况下,需要加载大量组件时,使用异步组件可以减少应用的初始化加载时间。或者需要更好地管理代码分割时,可以使用异步组件来提高应用程序的性能和可维护性。
14、何时需要使用keep-alive
- 组件需要频繁的显示和隐藏
- 组件的状态需要缓存
- 组件需要异步加载
15、何时需要使用beforeDestory
- 解绑自定义事件
- 清除定时器
- 解绑自定义的DOM事件
16、什么是作用域插槽
作用域插槽是Vue中的一个高级特性,它允许父组件向子组件传递一个带有作用域的插槽,让子组件可以在插槽内部访问父组件的数据和方法。
通常情况下,插槽只能传递简单的数据类型,比如字符串、数字等等。但是,当你需要在插槽内部访问复杂的数据结构,或者需要在插槽内部使用父组件的方法时,就可以使用作用域插槽来实现。
作用域插槽的使用方式与普通插槽类似,只需要在父组件中使用<slot>标签,并在该标签上添加一个名字,例如:
<template>
<child-component>
<template v-slot:default="slotProps">
{{ slotProps.parentData }}
</template>
</child-component>
</template>
在子组件中,你可以通过$slotProps来访问父组件传递过来的数据和方法,例如:
<template>
<div>
<slot :parentData="data"></slot>
</div>
</template>
<script>
export default {
data() {
return {
data: 'Hello World'
}
}
}
</script>
17、Vuex中action和mutation有何区别
- mutation只能执行同步操作,action可以用于异步操作
- mutation可以被devtools跟踪,而action则不行。
18、Vue-router 常用的路由模式
有两种:hash模式和history模式。
- hash模式是指URL中的hash(#)符号来模拟一个完整的URL。
- history模式是指使用HTML5中的historyAPI来实现URL的变化。
如果不需要考虑SEO,可以选择hash模式,因为它兼容性好,不需要服务器端支持。如果需要考虑SEO,则选择history模式,因为它的URL更美观。
19、如何配置Vue-router异步加载
1、可以通过Webpack的动态import语法来实现。需要配置路由的path路径和component。 2、在webpack的配置文件中开启代码分割,以便将路由组件打包成独立的文件。
20、请用vnode描述一个DOM结构
{
tag: 'div',
props: {
class: 'container',
id: 'main'
},
children: [
{
tag: 'h1',
props: {},
children: 'Hello World!'
}
]
}
这是一个包含一个div元素,它有一个class属性和一个id属性,它的子元素包括一个h1元素。
21、监听data变化的核心API是什么
Vue中监听data变化的核心API是Object.defineProperty。Vue通过这个API实现了数据劫持,可以在data属性变化时,能够自动触发更新操作。缺点是只能监听对象的属性,不能监听对象的新增属性和删除属性。还有如果对象的属性是嵌套对象,那么需要使用递归的方式来监听其内部属性的变化,
22、Vue如何监听数组变化
Vue会重新定义原型,重写push、pop等方法,实现监听。还可以使用watch来监听数组变化。
23、请描述响应式原理
Vue的响应式原理是通过数据劫持实现的。当Vue实例化时,它会遍历数据对象的每个属性,使用Object.defineProperty方法将它们转换为getter和setter。这样在数据发生变化时,setter会被调用,通知依赖于该数据的所有组件进行重新渲染。
vue组件渲染过程包括:
(1)解析模版:Vue会将组件的模版解析成一个抽象语法树(AST),这个AST描述了模版的结构和指令等信息。
(2)创建虚拟DOM:根据AST,Vue会创建一个虚拟DOM,它是一个轻量级的Javascript对象,描述了组件的结构和属性等信息。
(3)生成真实DOM:Vue会将虚拟DOM转换成真实DOM,并插入页面中。
(4)挂载组件:组件被挂载到页面后,Vue会调用组件的生命周期函数,执行一些初始化操作。
Vue组件更新过程包括:
(1)数据更新:当组件的数据发生变化时,Vue会自动触发数据更新。
(2)重新渲染虚拟DOM:Vue会根据数据变化,重新生成虚拟DOM。
(3)更新真实DOM:Vue会将新生成的虚拟DOM与旧的虚拟DOM进行比较,找出需要更新的部分,并将其更新到真实DOM中。
(4)调用生命周期函数:更新完成后,Vue会调用组件的生命周期函数,执行一些更新后的操作。
24、diff算法的事件复杂度
Vue中diff算法时间复杂度是O(n),其中n表示虚拟DOM树的节点数。然而在Vue2版本中,diff算法的时间复杂度是O(n^3),主要是因为在对虚拟DOM比较时,采用了一些暴力匹配的策略。为了优化这个问题,使用了几个策略:
- 增加key属性:每个节点增加key属性,在比较虚拟DOM时,只对同一个key的节点进行比较。
- 双端比较:从新旧节点的两端开始比较,依次向中间靠拢。
- 拆分长列表:将其拆分成多个小列表,并分别进行比较。
- patch补丁:在比较过程中,Vue会记录下所有需要进行变更的节点,一次性进行patch操作。
25、简述diff算法过程
- 比较新旧虚拟DOM树的根节点,如果节点类型不同,则直接用新节点。
- 如果节点类型相同,则比较节点属性,将新节点中有变化的属性更新到旧节点上。
- 如果节点有子节点,则递归比较子节点,如果子节点有变化,则更新子节点。
- 如果新节点的子节点数量大于旧节点,则将多余的子节点添加到旧节点上。
- 如果新节点的子节点数量小于旧节点,则将多余的旧节点删除。
26、Vue为何是异步渲染,$nextTick何用
这是因为在Vue中,数据的更新会导致重新渲染,而重新渲染需要一定的时间。如果同步更新数据符合渲染组件,会导致用户界面卡顿,影响用户体验。因此,Vue采用异步渲染的方式,将数据更新和组件渲染分开,先更新数据,再在下一个时间循环中渲染组件,这样可以提高应用的性能和用户体验。
nextTick是Vue提供的一个方法,用于在组件渲染完成后执行回调函数。
27、Vue常见性能优化方式
- 合理使用v-show和v-if
- 合理使用computed
- 使用v-for时配置key属性,以及避免和v-if同时使用
- data层级不要太深
- 使用vue-loader在开发环境做模版编译
- 合理使用keep-alive
- 自定义事件、DOM事件、定时器及时销毁
- 合理使用异步组件
- webpack层面的优化
- 前端通用的性能优化,如图片懒加载
- 使用SSR。服务器端渲染(Server Side Rendering)