Vue 面试题整理

274 阅读7分钟

1.vue组件的通信方式

  1. 通过 props 传递
  2. 通过 $emit 触发自定义事件
  3. 使用 ref
  4. EventBus
  5. parentparent 或root
  6. attrs 与 listeners
  7. Provide 与 Inject
  8. Vuex

2.$nextTick的作用

在下次 DOM 更新循环结束之后执行的延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。主要思路就是采用微任务优先的方式调用异步方法去执行 nextTick 包装的方法。

3.Vue 的生命周期

生命周期描述
beforeCreate组件实例被创建之初
created组件实例已经完全创建
beforeMount组件挂载之前
mounted组件挂载到实例上去之后
beforeUpdate组件数据发生变化,更新之前
updated组件数据更新之后
beforeDestroy组件实例销毁之前
destroyed组件实例销毁之后

4.Vue 中组件生命周期的调用顺序

加载渲染过程

父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount- >子mounted->父mounted

子组件更新过程

父beforeUpdate->子beforeUpdate->子updated->父updated

父组件更新过程

父 beforeUpdate -> 父 updated

销毁过程

父beforeDestroy->子beforeDestroy->子destroyed->父destroyed

5.做过哪些Vue的性能优化?

  • 尽量减少data中的数据,data中的数据都会增加getter和setter,会收集对应的watcher
  • v-if和v-for不能连用
  • 如果需要使用v-for给每项元素绑定事件时使用事件代理
  • SPA 页面采用keep-alive缓存组件
  • key保证唯一
  • 使用路由懒加载、异步组件
  • 防抖、节流
  • 长列表滚动到可视区域动态加载
  • 图片懒加载
  • 服务端渲染SSR
  • 压缩代码
  • Tree Shaking/Scope Hoisting
  • 使用cdn加载第三方模块
  • 多线程打包happypack
  • splitChunks抽离公共文件
  • sourceMap优化
  • 骨架屏
  • PWA

6.computed 和 watch 的区别

computed 计算属性 : 依赖其它属性值,并且 computed 的值有缓存,只有它依赖的属性值发生改变,下一次获取 computed 的值时才会重新计算 computed 的值。

watch 侦听器 : 更多的是「观察」的作用,无缓存性,类似于某些数据的监听回调,每当监听的数据变化时都会执行回调进行后续操作。

7.对 keep-alive 的了解

keep-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,避免重新渲染 ,其有以下特性:

  • 一般结合路由和动态组件一起使用,用于缓存组件;
  • 提供 include 和 exclude 属性,两者都支持字符串或正则表达式, include 表示只有名称匹配的组件会被缓存,exclude 表示任何名称匹配的组件都不会被缓存 ,其中 exclude 的优先级比 include 高;
  • 对应两个钩子函数 activated 和 deactivated ,当组件被激活时,触发钩子函数 activated,当组件被移除时,触发钩子函数 deactivated。

8.Vue3.0里为什么要用 Proxy API 替代 defineProperty API ?

Object.defineProperty 的缺点如下:

  • 检测不到对象属性的添加和删除
  • 数组API方法无法监听到
  • 需要对每个属性进行遍历监听,如果嵌套对象,需要深层监听,造成性能问题 Object.defineProperty 的优势如下:
  • 兼容性好,支持 IE9,而 Proxy 的存在浏览器兼容性问题,而且无法用 polyfill 磨平 Proxy 的优势如下:
  • Proxy 可以直接监听对象而非属性;
  • Proxy 可以直接监听数组的变化;
  • Proxy 有多达 13 种拦截方法,不限于 apply、ownKeys、deleteProperty、has 等等是 Object.defineProperty 不具备的;

9.Vue 的常用指令

  • v-bind
  • v-text
  • v-html
  • v-show
  • v-if
  • v-for
  • v-on
  • v-model
  • v-pre
  • v-cloak

10.delete和Vue.delete删除数组的区别

delete只是被删除的元素变成了 empty/undefined 其他的元素的键值还是不变。Vue.delete 直接删除了数组 改变了数组的键值。

11.Vue 有了数据劫持为什么还要 DOM diff?

数据劫持需要对数据绑定一个 Watcher,如果粒度太细会产生较大开销,因此 Vue 选择在组件级别 Watcher,而组件内部采用 DOM Diff

12.Vue3.0 的新特性与优化

  • diff算法优化,相比vue2增加了静态标记,其作用是为了会发生变化的地方添加一个flag标记,下次发生变化的时候直接找该地方进行比较
  • 静态提升,对不参与更新的元素,会做静态提升,只会被创建一次,在渲染时直接复用
  • 事件监听缓存
  • SSR优化
  • 移除了一些不常用的API,支持Tree shanking,打包的整体体积变小
  • vue2中采用 defineProperty来劫持整个对象,然后进行深度遍历所有属性,给每个属性添加getter和setter,实现响应式,vue3采用proxy重写了响应式系统,不需要深度遍历
  • Vue3 由TS重写,相对于 Vue2 有更好地TypeScript支持。
  • Vue3 提供Teleport组件可将部分DOM移动到 Vue app之外的位置
  • Vue3 提供 Suspense组件,允许程序在等待异步组件时渲染兜底的内容,如 loading
  • Vue3 支持了多根节点组件,也就是fragment。

13.Vue3.0 所采用的 Composition Api 与 Vue2.x 使用的 Options Api 有什么不同?

通常使用Vue2开发的项目,普遍会存在以下问题:

  • 代码的可读性随着组件变大而变差
  • 每一种代码复用的方式,都存在缺点
  • TypeScript支持有限 在Vue2中,我们是用过mixin去复用相同的逻辑 mixin复用代码逻辑存在明显的两个问题:
  • 命名冲突
  • 数据来源不清晰

在 Vue3 Composition API 中,组件根据逻辑功能来组织的,一个功能所定义的所有 API 会放在一起(更加的高内聚,低耦合)

即使项目很大,功能很多,我们都能快速的定位到这个功能所用到的所有 API

  • 在逻辑组织和逻辑复用方面,Composition API是优于Options API
  • 因为Composition API几乎是函数,会有更好的类型推断。
  • Composition API中见不到this的使用,减少了this指向不明的情况
  • 如果是小型组件,可以继续使用Options API,也是十分友好的

14.vue-router 路由钩子函数是什么?执行顺序是什么?

路由钩子的执行流程, 钩子函数种类有:全局守卫、路由守卫、组件守卫

完整的导航解析流程:

  • 导航被触发。
  • 在失活的组件里调用 beforeRouteLeave 守卫。
  • 调用全局的 beforeEach 守卫。
  • 在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
  • 在路由配置里调用 beforeEnter。
  • 解析异步路由组件。
  • 在被激活的组件里调用 beforeRouteEnter。
  • 调用全局的 beforeResolve 守卫 (2.5+)。
  • 导航被确认。
  • 调用全局的 afterEach 钩子。
  • 触发 DOM 更新。
  • 调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。

15.vuex有哪几种属性

有五种,分别是State , Getter , Mutation , Action , Module

  1. state:vuex的基本数据,用来存储变量

  2. geeter:从基本数据(state)派生的数据,相当于state的计算属性

  3. mutation:提交更新数据的方法,必须是同步的(如果需要异步使用action)。每个mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数,提交载荷作为第二个参数。

  4. action:和mutation的功能大致相同,不同之处在于 ==》1. Action 提交的是 mutation,而不是直接变更状态。 2. Action 可以包含任意异步操作。

  5. modules:模块化vuex,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。

16.Vue 常见的事件修饰符及其作用

  • .stop:阻止了事件冒泡,相当于调用了event.stopPropagation方法
  • .prevent :阻止了事件的默认行为,相当于调用了event.preventDefault方法
  • .capture :使事件触发从包含这个元素的顶层开始往下触发
  • .self :只会触发自己范围内的事件,不包含子元素;
  • .once :只会触发一次。
  • .native :让组件变成像html内置标签那样监听根元素的原生事件,否则组件上使用 v-on 只会监听自定义事件。

17.Vue 响应式原理

整体思路是数据劫持+观察者模式

对象内部通过 defineReactive 方法,使用 Object.defineProperty 将属性进行劫持(只会劫持已经存在的属性),数组则是通过重写数组方法来实现。当页面使用对应属性时,每个属性都拥有自己的 dep 属性,存放他所依赖的 watcher(依赖收集),当属性变化后会通知自己对应的 watcher 去更新(派发更新)。