Vue面试题真题笔记

v-show 和 v-if 区别

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

为何在 v-for 中使用 key

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

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

  • 挂载阶段 created mounted

    created 并未开始渲染,Vue 实例已初始化完毕,仅存在于内存
    mounted 渲染完毕

  • 更新阶段 updated
  • 销毁阶段 destroyed

(父子组件)

  • created 创建:外到内(父到子)
  • mounted 渲染:内到外
  • updated 更新:由外到内开始,由内到外结束
  • destroyed 销毁:由外到内开始,由内到外结束

Vue 组件如何通讯 (常见)

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

描述组件的渲染更新过程

Vue面试题真题笔记

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

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

对于 MVVM 的理解

Vue面试题真题笔记

computed 有何特点

  • 缓存,data 不变不会重新计算
  • 提高性能

为何组件 data 必须是一个函数

  • Object 是引用数据类型,如果不用 function 返回,每个组件的 data 都是内存的同一个地址,一个数据改变了其他也改变了
  • JavaScript 只有函数构成作用域(注意理解作用域,只有函数{}构成作用域,对象的{}以及 if(){}都不构成作用域,data 是一个函数时,每个组件实例都有自己的作用域,每个实例相互独立,不会相互影响。

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

  • mounted
  • JS 是单线程,ajax 异步获取数据
  • 放在 mounted 之前没有用 (存在异步队列中),只会让逻辑更加混乱

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

  • $props

如何自己实现 v-model

<template>
  <!-- 例如:vue 颜色选择 -->
  <input type="text" :value="text1" @input="$emit('change1', $event.target.value)" />
  <!--
        1. 上面的 input 使用了 :value 而不是 v-model
        2. 上面的 change1 和 model.event1 要对应起来
        3. text1 属性对应起来
    -->
</template>

<script>
  export default {
    model: {
      prop: 'text1', // 对应 props text1
      event: 'change1',
    },
    props: {
      text1: String,
      default() {
        return ''
      },
    },
  }
</script>

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

  • mixin
  • 缺点

何时要使用异步组件

  • 加载大组件
  • 路由异步加载

何时需要使用 keep-alive

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

何时需要使用 beforeDestroy

  • 解绑自定义事件 event.$off
  • 清除定时器
  • 解绑自定义 DOM 事件,如 window scroll 等

什么是作用域插槽

Vuex 中 action 和 mutation 区别

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

Vue-router 常用的路由模式

  • hash 默认
  • H5 history 需服务端支持
  • 二者比较

如何配置 vue-router 异步加载

  • component: () => import('./xxx')

用 vnode 描述一个 DOM 结构

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

监听 data 变化的核心 API

  • Object.defineProperty
  • 深度监听、监听数组
  • 缺点

Vue 如何监听数组变化

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

描述响应式原理

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

diff 算法的时间复杂度

  • O(n)
  • 在 O(n^3) 基础上做了一些调整

简述 diff 算法过程

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

Vue 为何是异步渲染,$nextTick 何用

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

Vue 常见性能优化方式

  • 合理使用 v-show 和 v-if
  • 合理使用 computed
  • v-for 加 key ,避免和 v-if 同时使用
  • 自定义事件、DOM 事件及时销毁
  • 合理使用异步组件
  • 合理使用 keep-alive
  • data 层级不要太深
  • 使用 vue-loader 在开发环境进行模板编译(预编译)
  • webpack 层面的优化
  • 前端通用的性能优化,如图片懒加载
  • 使用 SSR
上一篇:react router


下一篇:Vue.js-组件通信