vue2.X 高频面试题总结

218 阅读7分钟

组件中data必须用函数返回一个对象?、

  • data是一个函数时,每复用一次组件,就会返回一份新的data数据,每个组件实例都有自己的作用域,每个实例相互独立,互不影响。
  • 如果是对象形式,object是引用数据类型,每个组件的data都是内存的同一个地址,就会使用组件实例共用一份data数据一个数据改变,其他的也会改变。

Vue中key属性的作用

key 的特殊属性主要用在 Vue 的虚拟 DOM 算法,在新旧 nodes 对比时辨识 VNodes。

  • 如果不使用 key,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试修复/再利用相同类型元素的算法。
  • 使用 key,它会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素。

key值的存在保证了唯一性,可以用于dom的重新渲染或是就地复用。

vue在执行时,会对节点进行检查,如果没有key值,那么,vue检查到这里有dom节点,则会对内容进行清空,并且赋予新值;如果有key值的存在,那么vue会对oldnode和newnode进行对比,发现两者key值是否相同,进行调换位置或是删除操作。

key值的作用是:

更精准-->在虚拟dom节点中赋予key值,会更加快速的拿到需要的目标节点,不会造成就地复用的情况,对于节点的把控更加精准。

使用key给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点,为了高效的更新虚拟DOM。

vue中为啥不用index作为key?

  • 最好的处理方式,使用插件shortid -应该如何处理:
    • 用组件唯一的ID(后端返回)作为它的key,没有情况下,可以在获取到列表的时候通过某种规则为他们创建一个key,并保证这个key在组件整个生命周期中都保持稳定
    • 不用index作为key,因为不管数组的顺序怎么颠倒,index都是0,1,2这样的排列,导致vue会复用错误的旧子节点,做额外的工作
    • 不用使用随机数作为key,不然旧节点会被全部删除,新节点重新创建。

computed和watch的区别和运用场景?

  • computed:计算属性,依赖其它属性值,并且computed的值有缓存,只有它依赖的属性值发生改变,下一次获取computed的值才会重新计算computed的值
  • watch:更多的是[观察]的作用,类似于某些数据的监听回调,每当监听的数据变化时都会执行回调进行后续操作
computed运用场景:

当需要进行数值计算时,并且依赖其它数据时,应该用computed,因为可以利用computed的缓存特性,避免每次获取值时,都要重新计算。

  • 数组的过滤器(对返回的数据进行处理)
  • 计算总价格
watch运用场景

需要在数据变化执行异步或开销较大的操作时,应该用watch,使用watch选项允许我们执行异步操作。

  • 监听路由的变化
  • 监控自身属性的变化
  • 搜索框
vue是如何对数组数据进行监听的

数组的方法(push/pop/shift/unshift/splice/sort/reverse)重写

  • 获取原生Array的原型方法,
  • 对Array的原型方法使用Object.defineProperty进行拦截
  • 需要把拦截的Array类型的数据原型指向改造后的原型
为啥可以用$set检测数组变动
  • 因为set函数中,如果target是一个数组且索引有效,就设置length的属性
  • 通过splice方法把value设置到target数组指定位置
  • 设置时,vue会拦截到target发生变化,会把新增的value变成响应式
  • 最后返回value

nextTick与$nextTick的区别

  • nextTick(callback):当数据发生变化,更新后执行的回调。在下次DOM更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的DOM
  • $nextTick(callback):当dom发生变化,更新后执行的回调。将回调延迟到下次DOM更新循环之后执行。在修改数据之后立即使用,等待DOM更新。 区别:
  • nextTick(callback)是全局方法
  • $nextTick(callback)是回调的this自动绑定到调用它的实例上。

keep-alive的理解

keep-alive是vue内置的一个组件:它本身不会渲染一个DOM元素,也不会出现在父组件链中;使用keep-alive包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。 有以下特性:

  • 一般结合路由和动态组件使用,用于缓存组件;
  • 提供includeexclude属性
  • 对应两个钩子函数activateddeactivated,当组件被激活时,触发钩子函数activated,组件移除时,触发钩子函数deactivated。 原理解析:
  • 在created中创建缓存列表和缓存组件的key列表
  • destroyed销毁时会做一个循环销毁清空所有的缓存和key
  • mounted会监控include和exclude属性,进行组件的缓存处理
  • render渲染函数,会默认拿插槽,只缓存第一个组件,取出组件的名字,判断是否在缓存中,在就缓存,不在就return掉。

slot的理解

插槽

  • 创建组件虚拟节点时,会将组件儿子虚拟节点保存起来。当初始化组件时,通过插槽属性将儿子进行分类
  • 渲染组件时会拿对应的slot属性的节点进行替换操作(插槽的作用域为父组件) 作用域插槽
  • 作用域插槽在解析的时候不会作为作为组件的孩子节点。会解析成函数,当子组件渲染时,会调用此函数进行渲染
  • 普通插槽渲染的作用域是父组件,作用域插槽的渲染作用域是当前子组件

mixin

功能:抽离公共的业务逻辑 原理类似“对象的继承” 当组件初始化时会调用mergeOptions方法进行合并,采用策略模式针对不同的属性进行合并。当组件和混入对象含有同名选项时,这些选项将以恰当的方式进行合并

写过自定义指令么?原理是什么?

指令本质是装饰器,是vue对HTML元素的扩展,给Html元素增加自定义功能。 自定义指令有五个生命周期:

    1. bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
    1. inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
    1. update:被绑定于元素所在的模板更新时调用,而无论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新。
    1. componentUpdated:被绑定元素所在模板完成一次更新周期时调用。
    1. unbind:只调用一次,指令与元素解绑时调用。

created mounted请求数据的区别

  • created:vue实例的数据对象data有了,el模版还没有创建
  • mounted:vue实例挂在挂载已经完成

总结:

  • 对于作为子组件被调用的组件里,异步请求应当在mounted里调用,因为这个时候子组件可能需要涉及到对dom的操作;
  • 对于页面级组件,当我们需要使用ssr(服务端渲染)的时候,只有created是可用的,所以这个时候请求数据只能用它;
  • 对于页面级组件, 当我们做异步操作时,涉及到要访问dom的操作,我们仍旧只能使用mounted;
  • 对于一般情况,createdmounted都是可以的;

vue3是如何处理vue2中的mixins

组件之间共享相同的属性时,可以将公共属性提取到一个单独的模块中,使用mixins

mixins的缺点

  • 命名冲突 mixin在运行时合并两个对象,本地会覆盖mixin选项