目录

1. 对MVVM原理的理解

2. 请说一下响应式数据的原理

3. Vue中是如何检测数组变化的

    理解

    原理

   能改变数组的方法: 

4. 为何vue采用异步渲染

5. nextTick实现原理

6. Vue中Computed的特点

7. watch中的deep:true 是如何实现的

8. vue组件的生命周期

    掌握每个声明周期什么时候被调用

    要掌握每个声明周期内部可以做什么

9. ajax请求放在哪个生命周期中

10. 什么时候需要使用beforeDestory

11. Vue中v-if和v-show的区别

12. 为什么v-for和v-if不能连用

13. 用vnode来描述一个dom结构

14. diff算法的事件复杂度

15. 简述 Vue中diff算法原理


1. 对MVVM原理的理解

        * 传统的MVC指的是,用户操作会请求服务器路由,路由会调用对应的控制器来处理,控制器会获取数据,将结果返回给前端,页面重新渲染

        * MVVM:传统的前端会将数据手动渲染到页面上,MVVM模式不需要用户收到操作dom元素,将数据绑定到viewModel层上,会自动将数据渲染到页面中,视图变化会通知viewModel层更新数据,viewModel就是我们MVVM模式中的桥梁

2. 请说一下响应式数据的原理

    理解

        * 核心点:Object.defineProperty

        * 默认vue在初始化数据时,会给data中的属性使用Object.defineProperty重新定义所有属性,当页面取到对应属性时,会进行依赖收集(收集当前组件的watcher)如果属性发生变化会通知相关依赖进行更新操作。

   

    原理     

        initData(初始化用户传入的data数据)-->

        new Observer(将数据进行观测)-->

        this.walk(value)(进行对象的处理)-->

        defineReactive(循环对象属性定义响应式变化)-->

        Object.defineProperty(使用Object.definePorperty重新定义数据)

 

        拦截属性的获取,进行依赖收集,拦截属性的更新操作,对相关依赖进行通知

 

3. Vue中是如何检测数组变化的

    理解

        * 使用函数劫持的方式,重写了数组的方法

        * Vue将data中的数组,进行了原型链重写,指向了自己定义的数组原型方法,这样当调用数组api时,可以通知依赖更新,如果数组中包含着引用类型,会对数组中的引用类型再次进行监控

    原理

        initData(初始化用户传入的data数据)-->

        new Observer(将数据进行观测)-->

        protoAugment(value,arrayMethods)(对数组的原型方法进行重写,将数组的原型方法指向重写的原型)-->

        observerArray(深度观察数组中的每一项(对象类型))

 

   能改变数组的方法: 

            * push(方法可向数组的末尾添加一个或多个元素,并返回新的长度),

            * pop(删除并返回数组的最后一个元素),

            * shift(把数组的第一个元素从其中删除,并返回第一个元素的值),

            * unshift(向数组的开头添加一个或更多元素,并返回新的长度),

            * splice(从数组中添加/删除项目,然后返回被删除的项目),

            * sort(对数组的元素进行排序),

            * reverse(颠倒数组中元素的顺序)

 

4. 为何vue采用异步渲染

    理解

        * vue是组件级更新,数据改变,会重新渲染组件

        * 如果不采用异步更新,那么每次更新数据都会对当前组件进行重新渲染,所以为了性能考虑,Vue会在本轮数据更新后,再去异步更新视图

    原理 

        dep.notify()(通知watcher进行更新操作)-->

        subs[i].update()(依次调用watcher的update)-->

        queueWatcher(将watcher去重放到队列中)-->

        nextTick(flushSchedulerQueue)(异步清空watcher队列)

 

5. nextTick实现原理

    理解 

        * nextTick()就是将回调函数延迟在下一次dom更新数据后调用,

        * nextTick方法主要是使用宏任务和微任务,定义了一个异步方法,多次调用nextTick会将方法存入队列中,通过这个异步方法清空当前队列,所以这个nextTick方法是异步方法。

    原理

        nextTick(cb)(调用nextTick传入cb[cb:callback回调函数])-->

        callbacks.push(cb)(将回调函数存入数组中)-->

        timerFunc()(调用timerFunc)-->

        返回promise(支持promise的写法)

6. Vue中Computed的特点

        * 监控自己定义的变量,不在data里声明,直接在computed定义。

        * 多用于购物车

        * 默认computed也是一个watcher,是具备缓存的,只要当依赖的属性发生变化啊时才会更新视图

7. watch中的deep:true 是如何实现的

        * watch 监测vue实例上的数据变动

        * 当用户指定了watch中的deep属性为true时,如果当前监控的值是数组类型,会对对象中的每一项进行求值,此时会将当前watcher存入到对应属性的依赖中,这样数组中对象发生变化时也会通知数据更新

 

8. vue组件的生命周期

    掌握每个声明周期什么时候被调用

        * beforeCreate 在实例初始化之后,数据观测(data.observer)之前被调用

        * created 实例已经创建完成之后被调用,在这一步,实例已完成以下的配置:数据观测(data observer),属性和方法的运行,watch/event事件回调,这里还没有$el

        * beforeMount 在挂载开始之前被调用:相关的render函数首次被调用

        * mounted el被创建的vm.$el替换,并挂载到实例上去之后调用该钩子

        * beforeUpdate 数据更新时调用,发生在虚拟DOM重新渲染和打补丁之前

        * updated 由于数据更改导致虚拟DOM重新渲染和打补丁,在这之后会调用该钩子

        * beforeDestory 实例销毁之前调用,在这一步,实例仍然完全可用

        * destoryed Vue实例销毁后调用,调用后,Vue实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁,该钩子在服务器端渲染期间不被调用

    要掌握每个声明周期内部可以做什么

        * created 实例已经创建完成,因为它是最早触发的原因可以进行一些数据,资源的请求

        * mounted 实例已经挂载完成,可以进行一些DOM操作

        * beforeUpdate 可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程

        * updated 可以执行依赖于DOM的操作,然而在大多数情况下,你应该避免在此期间更改状态,因为可能会导致更新无限循环,该钩子在服务器端渲染期间不被调用

        * destoryed 可以执行一些优化操作,清空定时器,解除绑定事件。

 

9. ajax请求放在哪个生命周期中

        * 在created的时候,视图中的DOM并没有渲染出来,所以此时如果直接去操作dom节点,无法找到相关的元素

        * 在mounted中,由于此时dom已经渲染出来了,所以可以直接操作dom节点

        * 一般情况下都放到mounted中,保证逻辑的统一性,因为生命周期是同步执行的,ajax是异步执行的

        * 服务器端渲染不支持mounted方法,所以在服务器端渲染的情况下统一放到created中

10. 什么时候需要使用beforeDestory

        * 可能在当前页面使用了$on方法,那需要在组件销毁前解绑

        * 清除自己定义的定时器

        * 解除事件的绑定 scroll mousemove ……

11. Vue中v-if和v-show的区别

        * v-if 如果条件不成立不会渲染当前指令所在节点的dom元素

        * v-show 只是切换当前dom的显示或者隐藏

12. 为什么v-for和v-if不能连用

        * v-for 会比v-if的优先级高一些,如果连用的会把v-if给每个元素都添加一下,会造成性能问题

13. 用vnode来描述一个dom结构

        * 虚拟节点就是用一个对象来描述真实的dom元素
        

export function vnode(tag,data,key,children,text){
     return{
        tag, 
        data,
        key,
        children,
        text
     }
}

<div id="container"><p></p></div>

let obj={
    tag:'div',
    data:{
       id:'container'
    },
     children:[
        {
           tag:'p',
           data:{},
           childred:[]
        }
     ]
}

        template ast树 codegen render函数 内部调用 虚拟dom

 

14. diff算法的事件复杂度

 

        * 两个树的完全的diff算法是一个时间复杂度为o(n3),vue进行了优化o(n3)复杂度的问题转换为O(n)复杂度的问题,只比较同级不考虑跨级问题

        在前端中,很少跨越层级的移动dom元素,所以 virtual dom 只会对同一个层级的元素进行比较

 

15. 简述 Vue中diff算法原理

 

        * 先同级比较,在比较子节点

        * 先判断一方有儿子一方没儿子的情况

        * 比较都有儿子的情况

        * 递归比较子节点

学习记录

Logo

前往低代码交流专区

更多推荐