2024年3月份最新vue面试题汇总一、_vue面试题2024 pdf

原理:

    update () {    /* istanbul ignore else */    
        if (this.lazy) {      
            this.dirty = true    
            } else if (this.sync) {      
                this.run()    
            } else {     
                queueWatcher(this); // 当数据发生变化时会将watcher放到一个队列中批量更新   
            }
    } 
    export function queueWatcher (watcher: Watcher) {  
            const id = watcher.id // 会对相同的watcher进行过滤  
            if (has[id] == null) {    
                has[id] = true    
                if (!flushing) {      
                    queue.push(watcher)    
                    } else {      
                        let i = queue.length - 1      
                        while (i > index && queue[i].id > watcher.id) {        
                            i--     
                        }      
                        queue.splice(i + 1, 0, watcher)   
                        }    
                        // queue the flush    
                        if (!waiting) {     
                             waiting = true
                             if (process.env.NODE_ENV !== 'production' && !config.async) {        
                                flushSchedulerQueue()        
                                return      
                                }      
                                nextTick(flushSchedulerQueue) // 调用nextTick方法 批量的进行更新    
                        }  
                } 
    }

5.nextTick实现原理?
理解:(宏任务和微任务) 异步方法
nextTick 方法主要是使用了宏任务和微任务,定义了一个异步方法.多次调用 nextTick 会将方法存入 队列中,通过这个异步方法清空当前队列。 所以这个 nextTick 方法就是异步方法

原理:

        let timerFunc  // 会定义一个异步方法
        if (typeof Promise !== 'undefined' && isNative(Promise)) {  // promise  
        const p = Promise.resolve()  
        timerFunc = () => {    
            p.then(flushCallbacks)    
        if (isIOS) setTimeout(noop)  
        }  
            isUsingMicroTask = true 
        } else if (!isIE && typeof MutationObserver !== 'undefined' && ( // MutationObserver  
        isNative(MutationObserver) ||  MutationObserver.toString() === '[object MutationObserverConstructor]' )) {  
            let counter = 1  
            const observer = new MutationObserver(flushCallbacks)  
            const textNode = document.createTextNode(String(counter))  
            observer.observe(textNode, {    characterData: true  })  
        timerFunc = () => {    
            counter = (counter + 1) % 2    
            textNode.data = String(counter)  }  
            isUsingMicroTask = true 
        } else if (typeof setImmediate !== 'undefined' ) { // setImmediate  
        timerFunc = () => {    
            setImmediate(flushCallbacks)  
        } } else {  timerFunc = () => {   // setTimeout    
        setTimeout(flushCallbacks, 0)  } } // nextTick实现 
        export function nextTick (cb?: Function, ctx?: Object) {  
            let _resolve  
            callbacks.push(() => {    
                if (cb) {      
                    try {        
                        cb.call(ctx)      
                    } catch (e) {        
                        handleError(e, ctx, 'nextTick')      
                    }    
                } else if (_resolve) {      
                    _resolve(ctx)    
                }  
            })  
            if (!pending) {    
                pending = true    
                timerFunc()  
            } 
        }

6.Vue中Computed的特点 
理解: 默认 computed 也是一个 watcher 是具备缓存的,只要当依赖的属性发生变化时才会更新视图

原理:

        function initComputed (vm: Component, computed: Object) {  
            const watchers = vm._computedWatchers = Object.create(null)  
            const isSSR = isServerRendering()  for (const key in computed) {    
                const userDef = computed[key]    
                const getter = typeof userDef === 'function' ? userDef : userDef.get    
                if (!isSSR) {      // create internal watcher for the computed property.      
                watchers[key] = new Watcher(        vm,        getter || noop,        noop,        
                computedWatcherOptions      )    }
                 // component-defined computed properties are already defined on the    
                // component prototype. We only need to define computed properties defined
                // at instantiation here.    
                if (!(key in vm)) {      
                    defineComputed(vm, key, userDef)    
                } else if (process.env.NODE_ENV !== 'production') {      
                    if (key in vm.$data) {        
                        warn(`The computed property "${key}" is already defined in data.`, vm)      
                    } else if (vm.$options.props && key in vm.$options.props) {        
                        warn(`The computed property "${key}" is already defined as a prop.`, vm)     
                    }   
                }  
            }
        } 
        function createComputedGetter (key) {  
            return function computedGetter () {    
                const watcher = this._computedWatchers && this._computedWatchers[key]    
                if (watcher) {      
                    if (watcher.dirty) { // 如果依赖的值没发生变化,就不会重新求值        
                        watcher.evaluate()      
                    }      
                    if (Dep.target) {        
                        watcher.depend()      
                    }      
                    return watcher.value    
                }  
            } 
        }

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

原理:

        get () {    
            pushTarget(this) // 先将当前依赖放到 Dep.target上    
            let value    
            const vm = this.vm    
            try {      
                value = this.getter.call(vm, vm)   
            } catch (e) {      
                if (this.user) {        
                    handleError(e, vm, `getter for watcher "${this.expression}"`)      
                } else {        
                    throw e      
                }    
            } finally {      
                if (this.deep) { // 如果需要深度监控        
                    traverse(value) // 会对对象中的每一项取值,取值时会执行对应的get方法      
                }      
                    popTarget()  
            }
            return value 
        } 
        function _traverse (val: any, seen: SimpleSet) {  
            let i, keys 
            const isA = Array.isArray(val)  
            if ((!isA && !isObject(val)) || Object.isFrozen(val) || val instanceof VNode) {    
                return 
            }  
            if (val.__ob__) {    
                const depId = val.__ob__.dep.id    
                if (seen.has(depId)) {      
                    return    
                }    
                seen.add(depId) 
            }  
            if (isA) {    
                i = val.length    
                while (i--) _traverse(val[i], seen)  
            } else {    
            keys = Object.keys(val)    
            i = keys.length    
            while (i--) _traverse(val[keys[i]], seen)  
            } 
        }

8.Vue组件的生命周期


  

原理:


9.ajax请求放在哪个生命周期中
理解:
1.在created的时候,视图中的 dom 并没有渲染出来,所以此时如果直接去操 dom 节点,无法找到相 关的元素

2.在mounted中,由于此时 dom 已经渲染出来了,所以可以直接操作 dom 节点 
一般情况下都放到 mounted 中,保证逻辑的统一性,因为生命周期是同步执行的, ajax 是异步执行的
服务端渲染不支持mounted方法,所以在服务端渲染的情况下统一放到created中

10.何时需要使用beforeDestroy
理解:
1.可能在当前页面中使用了 $on 方法,那需要在组件销毁前解绑。

2.清除自己定义的定时器

3.解除事件的绑定 scroll mousemove …

11.Vue中模板编译原理
将 template 转化成 render 函数

12.Vue中v-if和v-show的区别
理解:
v-if 如果条件不成立不会渲染当前指令所在节点的 dom 元素

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

原理:

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

理解:

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

14.用vnode来描述一个DOM结构
虚拟节点就是用一个对象来描述真实的 dom 元素


15.diff算法的时间复杂度
 两个树的完全的 diff 算法是一个时间复杂度为 O(n3) , Vue 进行了优化·O(n3) 复杂度的问题转换成 O(n) 复杂度的问题(只比较同级不考虑跨级问题)  在前端当中, 你很少会跨越层级地移动Dom元素。 所 以 Virtual Dom只会对同一个层级的元素进行对比。 16.简述Vue中diff算法原理
理解:
1.先同级比较,在比较子节点
2.先判断一方有儿子一方没儿子的情况

3.比较都有儿子的情况

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值