1.vue组件的通信方式
- 通过 props 传递
- 通过 $emit 触发自定义事件
- 使用 ref
- EventBus
- root
- attrs 与 listeners
- Provide 与 Inject
- 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
-
state:vuex的基本数据,用来存储变量
-
geeter:从基本数据(state)派生的数据,相当于state的计算属性
-
mutation:提交更新数据的方法,必须是同步的(如果需要异步使用action)。每个mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数,提交载荷作为第二个参数。
-
action:和mutation的功能大致相同,不同之处在于 ==》1. Action 提交的是 mutation,而不是直接变更状态。 2. Action 可以包含任意异步操作。
-
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 去更新(派发更新)。