美文网首页
2021-06-25 「Vue源码学习(五)」面试官喜欢问的——

2021-06-25 「Vue源码学习(五)」面试官喜欢问的——

作者: 半眼鱼 | 来源:发表于2021-06-25 14:44 被阅读0次

    代码实现

    1.Vue.set

    export default function set(target, key, val) {
        if (Array.isArray(target)) {
            target.length = Math.max(target.length, key)
            target.splice(key, 1, val)
            return val
        }
    
        const ob = target.__ob__
    
        if (key in target && !(key in target.prototype) || !ob) {
            target[key] = val
            return val
        }
    
        defineReactive(target, key, val)
        return val
    }
    

    2.Vue.delete

    export default function del (target, key) {
        if (Array.isArray(target)) {
            target.splice(key, 1)
            return
        }
    
        const ob = target.__ob__
    
        if (!(key in target)) return
    
        delete target[key]
    
        if (!ob) return
    
        ob.dep.notify()
    }
    

    3.Vue.observable

    export default function observable (obj) {
        observable(obj)
        return obj
    }
    

    4.Vue.use

    export default function use (plugin) {
        const installedPlugins = this._installedPlugins || (this._installedPlugins = [])
        if (installedPlugins.indexOf(plugin) > -1) {
            return this
        }
    
        const args = toArray(arguments, 1); // 获取参数
        args.unshift(this); //在参数中增加Vue构造函数
    
        if (typeof plugin.install === 'function') {
            plugin.install.apply(plugin, args)
        } else if (typeof plugin === 'function') {
            plugin.apply(null, args)
        }
    
        installedPlugins.push(plugin)
        return this
    }
    

    5.nextTick

    let callbacks = []; //回调函数
    let pending = false;
    function flushCallbacks() {
      pending = false; //把标志还原为false
      // 依次执行回调
      for (let i = 0; i < callbacks.length; i++) {
        callbacks[i]();
      }
    }
    let timerFunc; //先采用微任务并按照优先级优雅降级的方式实现异步刷新
    if (typeof Promise !== "undefined") {
      // 如果支持promise
      const p = Promise.resolve();
      timerFunc = () => {
        p.then(flushCallbacks);
      };
    } else if (typeof MutationObserver !== "undefined") {
      // MutationObserver 主要是监听dom变化 也是一个异步方法
      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);
      };
    } else if (typeof setImmediate !== "undefined") {
      // 如果前面都不支持 判断setImmediate
      timerFunc = () => {
        setImmediate(flushCallbacks);
      };
    } else {
      // 最后降级采用setTimeout
      timerFunc = () => {
        setTimeout(flushCallbacks, 0);
      };
    }
    
    export function nextTick(cb) {
      callbacks.push(cb);
      if (!pending) {
        pending = true;
        timerFunc();
      }
    }
    

    相关文章

      网友评论

          本文标题:2021-06-25 「Vue源码学习(五)」面试官喜欢问的——

          本文链接:https://www.haomeiwen.com/subject/vvhoyltx.html