2024年3月份最新vue面试题汇总一、_vue面试题2024 pdf,这篇文章可以满足你80%日常工作

35 阅读5分钟
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 方法就是异步方法


**原理:**  
![](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/7d90ab3de72e41faa75e01ce8645c473~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3NTc5MjMwMTY3MDI=:q75.awebp?rk3s=f64ab15b&x-expires=1771410902&x-signature=fETNcrpJKY4%2BLNS7TM579Uxr9F8%3D)  
  



    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 是具备缓存的,只要当依赖的属性发生变化时才会更新视图** 


**原理:**  
![](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/1f3243dc6fd9402b9785cd7d31b172de~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3NTc5MjMwMTY3MDI=:q75.awebp?rk3s=f64ab15b&x-expires=1771410902&x-signature=U71cF24jMnt0D1CXNh7fZVBfjTA%3D)



    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组件的生命周期**


![](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/ab9476d98a394c0883c02ae6361a7673~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3NTc5MjMwMTY3MDI=:q75.awebp?rk3s=f64ab15b&x-expires=1771410902&x-signature=9OvIHMbo%2Bm%2FaPn9Yv7%2BeU%2BAsRpA%3D)


![](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/2e23e35c662b4a5d9ccd32ce3bfeb876~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3NTc5MjMwMTY3MDI=:q75.awebp?rk3s=f64ab15b&x-expires=1771410902&x-signature=FpCK93vblcpu34znxnzSZd2O5%2BA%3D)  
   ![](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/252b83768d7f490aa905b7e5d6fab97d~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3NTc5MjMwMTY3MDI=:q75.awebp?rk3s=f64ab15b&x-expires=1771410902&x-signature=J9NUx2e8hfs%2FSSeBZt5xvS20uz4%3D)


![](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/f19ca9d5b07c4a658bb2b4b44dc27fde~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3NTc5MjMwMTY3MDI=:q75.awebp?rk3s=f64ab15b&x-expires=1771410902&x-signature=ycBTwRXramRWwUE53F%2B1ZwnnjR4%3D)


**原理:**


![](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/b8e84ad428904c3b9f5ff8676c3cd7ae~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3NTc5MjMwMTY3MDI=:q75.awebp?rk3s=f64ab15b&x-expires=1771410902&x-signature=LldwfbyzDeUrXWPPC%2FaxvzWAB4s%3D)  
**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 函数  
![](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/3392fb83c2db4741a6c9343c0280722c~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3NTc5MjMwMTY3MDI=:q75.awebp?rk3s=f64ab15b&x-expires=1771410902&x-signature=Bc6Eh1REoMj%2F5aHKyRz4CUkudzg%3D)  
![](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/58f5c8ed1c334b7ab0919e7eb5ae53fa~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3NTc5MjMwMTY3MDI=:q75.awebp?rk3s=f64ab15b&x-expires=1771410902&x-signature=KqVYS4AxcRHS9f%2Bcxw9MM8o%2BlGQ%3D)![](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/55a1fedc0dd848caaedb1c32a87e48fe~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3NTc5MjMwMTY3MDI=:q75.awebp?rk3s=f64ab15b&x-expires=1771410902&x-signature=jNj7L8xPEwNhYlE6kEVIukJP0U8%3D)


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


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


**原理:**


![](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/28a5e83724924fa4a2cd513b626df15c~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3NTc5MjMwMTY3MDI=:q75.awebp?rk3s=f64ab15b&x-expires=1771410902&x-signature=PoveM9ZYV87zNViPfdG8wO2lfzg%3D)  



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


**理解:**  
![](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/334e5961373d44418ca94c1a5acb1990~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3NTc5MjMwMTY3MDI=:q75.awebp?rk3s=f64ab15b&x-expires=1771410902&x-signature=LTz2uJL22SVAQbiBUn8J6H40d6Q%3D)  
 v-for 会比 v-if 的优先级高一些,如果连用的话会把 v-if 给每个元素都添加一下,会造成性能问题


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


![](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/5f871afe7f8c47bfae772b5418a8c94d~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3NTc5MjMwMTY3MDI=:q75.awebp?rk3s=f64ab15b&x-expires=1771410902&x-signature=gs51YS%2FBw6xg24XZY8uZv47bGKs%3D)  
**15.diff算法的时间复杂度**  
  两个树的完全的 diff 算法是一个时间复杂度为 O(n3) , Vue 进行了优化·O(n3) 复杂度的问题转换成 O(n) 复杂度的问题(只比较同级不考虑跨级问题)  在前端当中, 你很少会跨越层级地移动Dom元素。 所 以 Virtual Dom只会对同一个层级的元素进行对比。 **16.简述Vue中diff算法原理**  
**理解:**  
 1.先同级比较,在比较子节点  
 2.先判断一方有儿子一方没儿子的情况


3.比较都有儿子的情况


4.递归比较子节点


![](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/622b6da144db480e88ef19085360ec26~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3NTc5MjMwMTY3MDI=:q75.awebp?rk3s=f64ab15b&x-expires=1771410902&x-signature=yL1otBzpCYvLp%2B4oYO5SvFW3r68%3D)  
**原理:**  
 core/vdom/patch.js


![](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/0e13ade3769642439b015c4aa017519c~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3NTc5MjMwMTY3MDI=:q75.awebp?rk3s=f64ab15b&x-expires=1771410902&x-signature=ji6IUpmy3QZ7%2FsEuB%2FnAPXhCdl0%3D)![](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/2720416ef5af49eb9422c22ed30529b4~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3NTc5MjMwMTY3MDI=:q75.awebp?rk3s=f64ab15b&x-expires=1771410902&x-signature=4xQYa6%2FVblPaPsR%2F%2BDmTmSxU6NY%3D)  
![](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/5bd09c332bcc4f0589f8b88fe46095a9~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3NTc5MjMwMTY3MDI=:q75.awebp?rk3s=f64ab15b&x-expires=1771410902&x-signature=lDYpeQGrhJ%2FcxUJTZ0CcUO4p1es%3D)


未完待续.....


最后为了方便大家的沟通与交流请加QQ群: [625787746]( )


### 最后

如果你已经下定决心要转行做编程行业,在最开始的时候就要对自己的学习有一个基本的规划,还要对这个行业的技术需求有一个基本的了解。有一个已就业为目的的学习目标,然后为之努力,坚持到底。如果你有幸看到这篇文章,希望对你有所帮助,祝你转行成功。



![](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/614082100d324e6ea4d1db195c61bdbe~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3NTc5MjMwMTY3MDI=:q75.awebp?rk3s=f64ab15b&x-expires=1771410902&x-signature=tnTJkDz71Gmg3RvuC9RXVkQ5JsE%3D)
**开源分享:https://docs.qq.com/doc/DSmRnRGxvUkxTREhO**