VUE面试题汇总---持续更新

160 阅读6分钟

1.生命周期函数

  • 1.什么是vue生命周期?

    Vue 实例从创建到销毁的过程,就是生命周期。也就是从开始创建、初始化数据、编译模板、挂载DOM-渲染、更新-渲染、卸载等一系列的过程,我们称这是 Vue 的生命周期。

  • 2.vue生命周期的作用是什么

    它的生命周期中有多个事件钩子,让我们在控制整个Vue实例的过程时更容易形成好的逻辑。 Vue 所有的功能的实现都是围绕其生命周期进行的,在生命周期的不同阶段调用对应的钩子函数可以实现组件数据管理和DOM渲染两大重要功能。

  • 3.第一次页面加载会触发哪几个钩子?

      beforeCreate , created , beforeMount ,mounted 这几个钩子
    
  • 4.父子组件的生命周期

      执行顺序:
      父组件开始执行到beforeMount 然后开始子组件执行,最后是父组件mounted。
      如果有兄弟组件,父组件开始执行到beforeMount,
      然后兄弟组件依次执行到beforeMount,
      然后按照顺序执行mounted,最后执行父组件的mounted。
      当子组件挂载完成后,父组件才会挂载。
      当子组件完成挂在后,父组件会主动执行一次beforeUpdated/updated钩子函数(仅首次)
      父子组件在data变化中是分别监控的,但是更新props中的数据是关联的。
      销毁父组件时,先将子组件销毁后才会销毁父组件。
      兄弟组件的初始化(mounted之前)是分开进行,挂载是从上到下依次进行
      当没有数据关联时,兄弟组件之间的更新和销毁是互不关联的        
    

2.你知道key的作用吗?

    1.key的作用是主要是为了更高效的更新虚拟DOM
    2.vue在patch 过程中 判断两个节点是否是相同的节点是key是一个必要条件,渲染一组列表时,key是唯一标识,所以如果不定义key的话,vue只能认为比较的两个节点是同一个,会频繁的更新元素,使得整个patch过程比较低效,影响性能。
    3.避免使用数组索引做key,会导致一些隐蔽bug;vue中在使用相同标签元素过渡切换时,也会使用key属性,其目的也是为了让vue可以区分他们,否则vue只会替换其内部属性而不会触发过渡效果。
    4.在源码中可以知道,vue判断两个节点是否相同时主要判断两者的key和元素类型等,因为如果不设置key,它的值时undefined,则可能永远认为时两个相同节点,只能去做更新操作,这造成了大量的dom更新操作,明显不可取的
    源码中 找答案:src/core/vdom/patch.js  sameVnode()

3.双向绑定以及实现原理

1. vue中的双向绑定是一个指令v-modal,可以绑定一个动态值到视图,同时视图中变化能改变该值。 v-modal是语法糖,默认情况下相当于:value和@input
2.使用v-modal可以减少大量繁琐的事件处理代码,提高开发效率,代码可读性更好
3.通常在表单项上使用v-modal
4.原生的表单项可以直接使用v-modal,自定义组件上如果使用它需要在组件内绑定value并处理输入事件
5.我做过测试,输出包含v-modal模版的组件渲染函数,发现它会被转换为value属性的绑定以及一个事件监听,事件回调函数中会做相应变量更新操作,这说明实际上是vue的编译器完成的

1.v-model和sync修饰符有什么区别

    v-model表单项,子组件中可以控制事件和属性名
    .sync属性有父组件指定,且事件名称是固定的,子组件未来要更新这个属性$emit('update:XXX')

自定义组件使用v-model如果想要改变事件名或者属性名应该怎么做

4.你了解vue中的diff算法吗?

vue基于虚拟DOM做更新,diff是核心部分

在vue2.0中才引入了虚拟dom 一个组件 一个watch
如果没有diff 没有去比较 就不知道哪个更新
diff 其实是发生在了更新阶段

1. diff算法是虚拟DOM技术的产物,vue⾥⾯实际叫做patch,它的核⼼实现来⾃于snabbdom;
通过新旧虚拟DOM作对⽐(即patch),将变化的地⽅转换为DOM操作
2. 在vue 1中是没有patch的,因为界⾯中每个依赖都有专⻔的watcher负责更新,这样项⽬规模变⼤
就会成为性能瓶颈,vue 2中为了降低watcher粒度,每个组件只有⼀个watcher,但是当需要更新
的时候,怎样才能精确找到发⽣变化的地⽅?这就需要引⼊patch才⾏。
3. 组件中数据发⽣变化时,对应的watcher会通知更新并执⾏其更新函数,它会执⾏渲染函数获取全
新虚拟dom:newVnode,此时就会执⾏patch⽐对上次渲染结果oldVnode和新的渲染结果
newVnode。
4. patch过程遵循深度优先、同层⽐较的策略;两个节点之间⽐较时,如果它们拥有⼦节点,会先⽐
较⼦节点;⽐较两组⼦节点时,会假设头尾节点可能相同先做尝试,没有找到相同节点后才按照通
⽤⽅式遍历查找;查找结束再按情况处理剩下的节点;借助key通常可以⾮常精确找到相同节点,
因此整个patch过程⾮常⾼效。

5.vue中组件之间的通信⽅式?

1. 组件通信⽅式⼤体有以下8种:
    props ⽗⼦
    $emit/$on ⼦⽗
    $children/$parent ⽗⼦/⼦⽗
    $attrs/$listeners 爷孙
    Provide/inject
    ref ⽗⼦
    $root 任意
    eventbus 任意
    vuex 任意

 - 1.⽗⼦组件
        props
        $emit / $on
        $parent / $children
        ref
        $attrs / $listeners
- 兄弟组件
        $parent
        eventbus
        vuex        
- 跨层级关系
        provide / inject
        $root
        eventbus
        vuex    

6.简单说⼀说你对vuex理解?

   Vuex 是⼀个专为 Vue.js 应⽤程序开发的状态管理模式。
   它采⽤集中式存储管理应⽤的所有组件的状态,并以相应的规则保证状态以⼀种可预测的⽅式发⽣变化。 
   要遵循单项数据流        

    1.vuex是vue专⽤的状态管理库。它以全局⽅式集中管理应⽤的状态,并且可以保证状态变更的可预测性。
    2. vuex主要解决的问题是多组件之间状态共享的问题,利⽤各种组件通信⽅式,我们虽然能够做到状态共享,但是往往需要在多个组件之间保持状态的⼀致性,这种模式很容易出现问题,也会使程序逻辑变得复杂。
    vuex通过把组件的共享状态抽取出来,以全局单例模式管理,这样任何组件都能⽤⼀致的⽅式获取和修改状态,响应式的数据也能够保证简洁的单向数据流动,我们的代码将变得更结构化且易维护。
    3. vuex并⾮必须的,它帮我们管理共享状态,但却带来更多的概念和框架。
    如果我们不打算开发⼤型单⻚应⽤或者我们的应⽤并没有⼤量全局的状态需要维护,完全没有使⽤vuex的必要。
    ⼀个简单的store 模式就⾜够了。反之,Vuex 将会成为⾃然⽽然的选择。
    引⽤ Redux 的作者 DanAbramov 的话说就是:Flux 架构就像眼镜:您⾃会知道什么时候需要它。
    4. 我在使⽤vuex过程中有如下理解:⾸先是对核⼼概念的理解和运⽤,将全局状态放⼊state对象中,
    它本身⼀棵状态树,组件中使⽤store实例的state访问这些状态;
    然后有配套的mutation⽅法修改这些状态,并且只能⽤mutation修改状态,在组件中调⽤commit⽅法提交mutation;
    如果应⽤中有异步操作或者复杂逻辑组合,我们需要编写action,执⾏结束如果有状态修改仍然需要提交mutation,
    组件中调⽤这些action使⽤dispatch⽅法派发。最后是模块化,通过modules选项
    组织拆分出去的各个⼦模块,在访问状态时注意添加⼦模块的名称,如果⼦模块有设置
    namespace,那么在提交mutation和派发action时还需要额外的命名空间前缀。
    5. vuex在实现单项数据流时需要做到数据的响应式,通过源码的学习发现是借⽤了vue的数据响应化特性实现的,
    它会利⽤Vue将state作为data对其进⾏响应化处理,从⽽使得这些状态发⽣变化时,能够导致组件重新渲染。