一,面试题来源

  1. 自己觉得是面试重点
  2. 网上收集整理的面试题
  3. 热门技术和知识点

二,面试题集合

1,v-if 和 v-show 的区别?

  • v-show :通过 CSS display 控制显示和隐藏
  • v-if :组件真正的渲染和销毁,而不是显示和隐藏
  • 频繁切换显示状态使用 v-show,否则使用 v-if

2,为何在 v-for 中使用 key?

  • 必须使用 key,且不能是 index 和 random
  • diff 算法中通过 tag 和 key 来判断,是否是相同的 Node
  • 减少渲染次数,提升渲染性能

3,描述 Vue 组件生命周期(父子组件)

  • 单组件生命周期图
  • 父子组件生命周期关系

4,Vue 组件如何通讯?(常见)

  • 父子组件 props 和 this.$emit
  • 自定义事件 event.$on、event.$off、event.$emit
  • vuex

5,描述组件渲染和更新的过程

image.png

6,双向数据绑定 v-model 的实现原理

  • input 元素的 value = this.name
  • 绑定 input 事件 this.name = $event.target.value
  • data 更新触发 re-render

7,对 MVVM 的理解

image.png
MVVM 表示的是 Model-View-ViewModel

  • Model:模型层,负责处理业务逻辑以及和服务器端进行交互。
  • View:视图层,负责将数据模型转化为UI展示出来,可以简单的理解为HTML页面。
  • ViewModel:视图模型层,用来连接模型层和视图层,是模型层和视图层之间的通信桥梁。

    8,computed 有何特点?

  • 缓存,data 不变不会重新计算

  • 提高性能

9,为什么组件 data 必须是一个函数?

保证不同的数据之间不会相互影响,如何data 是一个对象的话,这一个页面修改的数据,可能会对两个页面产生影响,我们需要数据的相互独立,所以data 必须是一个函数

10,ajax 请求应该放在哪个生命周期?

  • mounted
  • JS 是单线程的,ajax 异步获取数据
  • 放在 mounted 之前没有用,只会让逻辑更加混乱(只有在mounted的时候,页面才渲染完毕,dom加载完毕,在这之前,页面是没有渲染完毕的,请求回来的ajax请求也需要排队,不能立即使用)

11,如何将组件所有的 props 传递给子组件?

  • $props
  • 细节知识点,优先级不高

12,如何自己实现 v-model ?

13,多个组件有相同的逻辑,如何抽离?

  • mixin
  • 以及 mixin 的一些缺点

14,何时要使用异步组件?

  • 加载大组件(加载编辑器,加载图表等)
  • 路由异步加载

15,何时需要使用 keep-alive ?

  • 缓存组件,不需要重复渲染
  • 如多个静态 tab 页的切换
  • 优化性能

16,何时需要使用 beforeDestory ?

  • 解绑自定义事件 event.$off
  • 清除定时器
  • 解绑指定的 DOM 事件,如 window scroll 等(避免内存泄漏,越用越卡,最后卡死)

17,什么是作用域插槽 ?

  1. <template>
  2. <div>
  3. <p>vue 高级特性</p>
  4. <hr>
  5. <ScopedSlotDemo :url="website.url">
  6. <!---{{website.title}}--->
  7. <template v-slot="slotProps">
  8. {{slotProps.slotData.title}}
  9. </template>
  10. </ScopedSlotDemo>
  11. </div>
  12. </template>
  13. <script>
  14. import SlotDemo from './SlotDemo'
  15. export default {
  16. components: {
  17. ScopeSlotDemo
  18. },
  19. data() {
  20. return {
  21. name: '双越',
  22. website: {
  23. url: 'http://imooc.com/',
  24. title: 'imooc',
  25. subTitle: '程序员的梦工厂'
  26. }
  27. }
  28. }
  29. }
  30. </script>

18,Vue 中的 action 和 mutation 有何区别?

  • action 中异步处理,mutation 不可以
  • mutation 做原子操作
  • action 可以整合多个 mutation

19,Vue-router 常用的路由模式

  • hash 默认
  • H5 history(默认服务端支持)
  • 两者比较,选择

20,如何配置 Vue-router 异步加载?

export default new VueRouter({
  routers: [
    {
      path: '/',
      component: () => import('./../components/Navagator')
    },
    {
    path: '/feedback',
    component: () => import('./../components/Feedback')
    }
  ]
})

21,请用一个 vnode 描述一个 DOM 结构

<div id="div1" class="container">
  <p>vdom</p>
  <ul style="font-size: 20px">
    <li>a</li>
  </ul>
</div>

{
  tag: 'div',
  props: {
    className: 'container',
    id: 'div1'
  },
  children: [
    {
      tag: 'p',
      children: 'vdom'
    },
    {
      tag: 'ul',
      props: { 
        style: 'font-size:20px'
      },
      children: [
        {
          tag: 'li',
          children: 'a'
        }
      ]
    }
  ]
}

22,监听 data 变化的核心 API 是什么?

  • Object.defineProperty
  • 以及深度监听、监听数组
  • 有何缺点?

23,Vue 如何监听数组变化?

  • Object.defineProperty 不能监听数组变化
  • 重新定义原型,重写 push、pop 等方法,实现监听
  • Proxy 可以原生支持监听数组变化

24,请描述响应式原理

  • 监听 data 变化
  • 组件渲染和更新的流程

25,diff 算法的时间复杂度

  • O(n)
  • 在 O(n^3) 基础上做了一些调整
    • 只进行同一层级的比较
    • 同一层级的 dom 不相同,直接进行销毁
    • 比较 sel 和 key,判断是否为 sameNode

26,简述 diff 算法的过程(拿snabbdom举例说明即可)

  • patch(elem, vnode) 和 patch(vnode, newVnode)
  • patchVnode 和 addVnodes、removeVnodes
  • updateChildren(key的重要性)

27,Vue 为何是异步渲染,$mextTick 何用?

  • 异步渲染(以及合并 data 修改),以提高渲染性能
  • $nextTick 在 DOM 更新完毕之后,触发回调

28,Vue 常见性能优化

  1. 合理使用 v-if 和 v-show
  2. 合理使用 computed
  3. v-for 时加 key,以及避免和 v-if 同时使用
  4. 自定义事件、DOM 事件及时销毁
  5. 合理使用异步组件
  6. 合理使用 keep-alive
  7. data 层级不要太深
  8. 使用 vue-loader 在开发环境下面做模板编译(预编译)
  9. webpack 层面的优化
  10. 前端通用的性能优化,如图片懒加载
  11. 使用 SSR