Vue2知识点汇总

123 阅读5分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

1、 Vue响应式数据的理解

当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的 property,并使用 Object.defineProperty 把这些 property 全部转为 getter/setter。Object.defineProperty 是 ES5 中一个无法 shim 的特性,这也就是 Vue 不支持 IE8 以及更低版本浏览器的原因。

2 、生命周期钩子是如何实现的?

生命周期描述
beforeCreatevue实例初始化后,数据观测(data observer)和事件配置之前。data、computed、watch、methods都无法访问。
createdvue实例创建完成后立即调用 ,可访问 data、computed、watch、methods。未挂载 DOM,不能访问el、ref。
beforeMount在 DOM 挂载开始之前调用。
mountedvue实例被挂载到 DOM。
beforeUpdate数据更新之前调用,发生在虚拟 DOM 打补丁之前。
updated数据更新之后调用。
beforeDestroy实例销毁前调用。
destroyed实例销毁后调用 。

3、Vue 中组件的 data 为什么是一个函数?

一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝

4、nextTick 在哪里使用?原理是?

根据浏览器的不同所所以兼容的API也不一样,兼容顺序

Promise
MutationObserver
setImmediate
setTimeout

5、Vue 组件间通讯方式

prop、emit、eventbus、.sync、 attrsattrs isteners、ref、插槽、vuex

  • 父子组件通讯
    • props 与 $emit
    • parent与children
  • 隔代组件通讯
    • attrs与listeners
    • provide 和 inject
  • 父子、兄弟、隔代组件通讯
    • EventBus
    • Vuex

6、Vue动态组件 is

<component:is="componentId"></component>

7、父子组件的生命周期(执行顺序)

完整的父子组件生命周期

父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate -> 子created -> 子beforeMount -> 子mounted -> 父mounted->父beforeUpdate->子beforeUpdate->子updated->父updated->父beforeDestroy->子beforeDestroy->子destroyed->父destroyed

  • 加载渲染过程 父先创建,才能有子;子创建完成,父才完整
    • 父 beforeCreate -> 父 created -> 父 beforeMount -> 子 beforeCreate -> 子 created -> 子 beforeMount -> 子 mounted -> 父 mounted
  • 子组件更新过程 子组件更新 影响到 父组件的情况。
    • 父 beforeUpdate -> 子 beforeUpdate -> 子 updated -> 父 updated
  • 子组件更新 不影响到 父组件的情况。
    • 子 beforeUpdate -> 子 updated
  • 父组件更新过程父组件更新 影响到 子组件的情况。
    • 父 beforeUpdate -> 子 beforeUpdate -> 子 updated -> 父 updated
  • 父组件更新 不影响到 子组件的情况。
    • 父 beforeUpdate -> 父 updated
  • 销毁过程
    • 父 beforeDestroy -> 子 beforeDestroy -> 子 destroyed -> 父 destroyed

8、v-if 和 v-show 的区别

v-if:如果为 false 默认不渲染 切换时会进行创建和销毁 会触发生命周期钩子 v-show:默认渲染 css 切换

9、v-if 与 v-for 的优先级

vue2 v-for 优先级高 vue3 v-if 优先级高

10、Vue常用的修饰符

stop:阻止冒泡 prevent:阻止默认行为 self:仅绑定元素自身触发 once:只触发一次

11、vue.set 方法是如何实现的?

  • Vue.prototype.$set = set
  • set 方法内部实现方式
    • defineReactive
    • ob.dep.notify() ob 通过Observe 给__ob__赋值 dep在get里赋值 notice 会调用 watcher的update 方法

13、Vue.mixin 的使用场景和原理

混入 (mixins) 是一种分发 Vue 组件中可复用功能的非常灵活的方式。混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被混入该组件本身的选项

同名数据对象对象在内部会进行浅合并 (一层属性深度),在和组件的数据发生冲突时以组件数据优先

同名钩子函数将混合为一个数组,因此都将被调用。另外,混入对象的钩子将在组件自身钩子之前调用

methods, components 和 directives,将被混合为同一个对象。两个对象键名冲突时,取组件对象的键值对

14、为什么 vue 或者 react 要求 key 值唯一

没有 Key 值的问题 老集合中包含节点:A、B、C、D,更新后的新集合中包含节点:B、A、D、C,此时新老集合进行 diff 差异化对比,发现 B != A,则创建并插入 B 至新集合,删除老集合 A;以此类推,创建并插入 A、D 和 C,删除 B、C 和 D。 因为这些都是相同的节点,但由于位置发生变化,导致需要进行繁杂低效的删除、创建操作,其实只要对这些节点进行位置移动即可。 针对这一现象,提出优化策略:允许开发者对同一层级的同组子节点,添加唯一 key 进行区分,虽然只是小小的改动,性能上却发生了翻天覆地的变化!

15、Vue @hook 在父组件监听子组件的生命周期方法

<Child @hook:mounted="handleChildMounted" @hook:beforeDestroy="handlebeforDestryed" @hook:destroyed="handleDestroyed" :data="data" />

16、Vue @hook 在父组件监听子组件的生命周期方法

Vue.prototype就是js函数原型对象的特性, 函数原型上的属性/方法, 在函数实例化后, 可以在任意实例上读取

17、attrsattrs和listeners 的使用

attrs属性就包含了所有父组件传来的数据(除开已经props声明了的)

当父组件传递了很多数据给子组件时,子组件没有声明props来进行接收,那么子组件中的attrs属性就包含了所有父组件传来的数据(除开已经props声明了的),子组件还可以使用v−bind="attrs属性就包含了所有父组件传来的数据(除开已经props声明了的),子组件还可以使用v-bind="attrs属性就包含了所有父组件传来的数据(除开已经props声明了的),子组件还可以使用v−bind="attrs"的形式向它的子组件(孙子组件)传递数据,孙子组件使用$attrs的方式和它的父组件原理类似。

listeners属性和attrs属性类似,只是它们传递的东西不一样

$listeners可以通过v-on的形式再次传递给下层组件,当父组件在子组件上定义了一些自定义的非原生事件时,在子组件内部可以通过listeners属性获取>父组件的自定义事件,它和attrs的区别很明显,attrs用来传递属性。

使用listeners的好处在于:如果存在多层级组件,无需使用emit的方式逐级向上触发事件,只需要使用$listerners就可以得到父组件中的自定义事件,相当于偷懒了。

inheritAttrs

父组件传递了很多数据给子组件,子组件的props没有完全接收,那么父组件传递的这些数据就会渲染到HTML上,我们可以给子组件设置inheritAttrs 为false,避免这样渲染。
child1组件示例代码:

data() {
  return {
    childStr: 'child String'
  };
},
  inheritAttrs: false,

总结

attrs:用来会传递属性,除了class、style之类的,它是一个对象。 listeners:用来传递事件,除了原生事件,它也是一个对象。
attrs和listeners这两个属性可以解决多层组件之间数据和事件传递的问题。
inheritAttrs解决未使用props接收的数据的属性渲染