基础
基础
- 谈谈你对vue的理解(vue是什么?)
- 怎样理解 Vue 的单向数据流?
- vue 中组件的注册和销毁组件
- vue组件里的定时器要怎么销毁?
- 实现 v-model 及多重绑定和原理
- 谈谈 keep-alive
- 你知道 vue 中 key 原理吗? 有什么作用?说说你对它的理解
- 谈谈 Object.defineProperty 和 proxy(就是考察 vue2 和 vue3 的区别)
- computed 和 watch 的区别和运用的场景? 底层实现有什么区别?分别在什么场景下使用?
既然 Vue 通过数据劫持可以精准探测数据变化,为什么还需要虚拟 DOM 进行 diff 检测差异?
在 vue1 版本中就只有 watcher,没有采用 diff 算法,所以这样会导致非常的耗性能, Vue2 内部设计原因导致,vue 设计的是每个组件一个 watcher(渲染函数 watcher),没有采用一个属性对应-个 watcher。这样会导致大量 watcher 的产生而且浪费内存,如果粒度过低也无法精准检测变化。所以采用diff 算法 + 组件级 watcher。
19. 说一下你对响应式数据的理解?(Vue2 和 Vue3 的响应式原理是什么?)
数组和对象类型当值变化时如何劫持到?
对象内部通过 defineReactive
方法,使用 object.defineProperty
将属性进行劫持(只会劫持已经存在的属性),数组则是通过重写数组方法来实现。多层对象是通过递归来实现劫持。 vue3 则采用 proxy
vue2 处理缺陷
- 在 vue2 的时候使用 defineProperty 来进行数据的劫持,需要对属性进行重写添加 getter 及 setter 性能差。
- 当新增属性和删除属性时无法监控变化。需要通过 delete 实现,就是改变 data 的对象时,vue 无法劫持到,需要通过 delete 实现。
- 数组不采用 defineProperty 来进行劫持(浪费性能,对所有索引进行劫持会造成性能浪费)需要对数组单独进行处理。
- 对于 ES6 中新产生的 Map、Set 这些数据结构不支持。
4. v-show 与 v-if 有什么区别?
- 区别:
- v-if 是真正的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建;也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
- v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 的 “display” 属性进行切换。
- 使用场景
- v-if 适用于在运行时很少改变条件,不需要频繁切换条件的场景;
- v-show 则适用于需要非常频繁切换条件的场景。
3 vue2 与 vue3 实现对比
Vue 中如何检测数组变化?
5. Class 与 Style 如何动态绑定?
Class 可以通过对象语法和数组语法进行动态绑定: https://github.com/haizlin/fe-interview/issues/437
/** 对象语法 */
<div v-bind:class="{ active: isActive, 'text-danger': hasError }"></div>
data: {
isActive: true,
hasError: false
}
/** 数组语法 */
<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>
data: {
activeClass: 'active',
errorClass: 'text-danger'
}
Style 也可以通过对象语法和数组语法进行动态绑定:
/** 对象语法 */
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
data: {
activeColor: 'red',
fontSize: 30
}
/** 数组语法 */
<div v-bind:style="[styleColor, styleSize]"></div>
data: {
styleColor: {
color: 'red'
},
styleSize:{
fontSize:'23px'
}
}
为什么白屏加载时间长?
因为在打包后的 index.html 里面,打包后的 js 脚本在最下面,所以首先是加载一个空的 div,然后再去加载哪些js脚本,这就会导致白屏时间过长。
8. 直接给一个数组项赋值,Vue 能检测到变化吗?($set 是什么?有什么作用?怎么实现的?在什么时候使用?)
9. vue绑定事件如何添加修饰符?
10. vue中的数据双向绑定是怎么实现的(双向绑定原理、怎么工作)?
11. Vue 组件中 data 为什么必须是函数?
12. Vue 组件间通信有哪些方式?
13. Vue 的生命周期钩子函数有哪些?怎么对应到组件渲染的不同阶段?
14. Vue 的父组件和子组件生命周期钩子函数执行顺序?
2. 父组件引入子组件,那么生命周期执行的顺序是?
父组件
beforeCreate
created
beforeMount
子组件 1
beforeCreate
created
beforeMount
mounted
子组件 2
beforeCreate
created
beforeMount
mounted
......
父组件
mounted
3. 怎么在 beforeCreate、created、beforeMount、mounted 中获取 DOM
- 只要在异步代码中获取就可以了,因为 vue 所有的生命周期都是同步的,所以异步代码最后才会执行,只要在里面写异步代码就可以了
例如:setTimeout、请求、Promise.xxx() 等等.
- 使用vue系统内置的 this.$nextrick
4. 为什么发送请求不在 beforeCreate 里? beforeCreate 和 created 有什么区别?
因为:如果请求是在 methods 封装好了,在 beforeCreate 调用的时候,beforeCreate 阶段是拿不到 methods 里面的方法的(会报错了)。
5. 发送请求在 created 还是 mounted ?
这个问题具体要看项目和业务的情况了,因为组件的加载顺序是,父组件引入了子组件,那么先执行父的前 3 个生命周期,再执行子的前 4 个生命周期,那么如果我们的业务是父组件引入子组件,并且优先加载子组件的数据,那么在父组件中当前的请求要放在mounted 中,如果当前组件没有依赖关系那么放在哪个生命周期中请求都是可以的。