Vue 基础面试题
1. Vue组件有哪些通信方式
答案:有挺多,下面是比较常见的几种
- props / $emit
这个是我们平时用得比较多的方式之一,父组件 A 通过 props 参数向子组件 B 传递数据,B 组件通过 $emit 向 A 组件发送一个事件(携带参数数据),A组件中监听 $emit 触发的事件得到 B 向 A 发送的数据。
- $emit / $on
这种方式是通过一个类似 App.vue 的实例作为一个模块的事件中心,用它来触发和监听事件,如果把它放在 App.vue 中,就可以很好的实现任何组件中的通信,但是这种方法在项目比较大的时候不太好维护。
- Vuex
Vuex 是一个状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
Vuex 应用的核心是 store(仓库,一个容器),store 包含着你的应用中大部分的状态 (state);
- $attrs / $listeners
- $parent / $children 与 ref
2. Vue的生命周期
-
beforeCreate —— 此时,刚刚初始化了一个vue的实例对象,这个时候,对象上只有生命周期函数和一些默认的事件,其他的东西都还未创建(data和methods都还未初始化)
-
created —— 此时,data和methods都被初始化好了,所以如果我们需要调用method里的方法和操作data里的数据,created是最早的操作时期。
-
beforeMount —— 在挂载开始之前被调用:相关的 render 函数首次被调用。
-
mounted —— el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。此时所有的dom都以及挂载完毕。
-
beforeUpdate —— 数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。
-
updated —— 由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。当这个钩子被调用时,组件 DOM 已经更新,所以现在可以执行依赖于 DOM 的操作。然而在大多数情况下,应该避免在此期间更改状态,因为可能会导致更新无限循环。
-
beforeDestroy —— 实例销毁之前调用。在这一步,实例仍然完全可用。
-
destroyed —— Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
3. 简述 Vue2.0 的双向绑定
Vue 的双向绑定,用到的是数据的劫持监听,使用Object.defineProperty( )这个方法
因为双向绑定涉及的是数据改变驱动视图改变,视图改变驱动数据,所以我们需要:
- 实现一个监听器Observer,对 data 里的属性递归遍历,并对其进行Object.defineProperty( ),用来劫持并监听所有属性,如果属性发上变化了,就通知订阅者者。
- 再实现一个订阅者Watcher,可以收到属性的变化通知并执行相应的函数,从而更新视图
- 因为订阅者是有很多个,所以我们需要有一个消息订阅器Dep来专门收集这些订阅者,在监听器Observer和订阅者Watcher之间进行统一管理的。接着,我们还需要有一个指令解析器Compile,对每个节点元素进行扫描和解析,将相关指令对应初始化成一个订阅者Watcher,并替换模板数据或者绑定相应的函数,此时当订阅者Watcher接收到相应属性的变化,可以扫描和解析每个节点的相关指令,并根据初始化模板数据以及初始化相应的订阅器。
VUE 3.0 的可以问问,和 2.0 不同
4. computed 和 watch 的区别
computed - 是用来计算出一个值,这个值在调用的时候会根据依赖的数据显示新的计算结果并自动缓存。 如果依赖不变,computed中的值就不会重新计算。
watch - 如果某个属性依赖变化了就执行回调。 它有俩个属性 1. immediate 表示数据是否在第一次渲染的时候立即执行该函数。 2. deep , 如果我们监听一个对象(不包括数组),是否要看对象里面的属性的变化。
总结:如果一个数据需要经过复杂计算就用 computed 、 如果一个数据需要在发生变化时做一些操作就用 watch