preface

Go, learn!! Welcome to this series of articles:

  • “Vue source code learning (a)” you don’t know – data responsive principle
  • “Vue source code learning (2)” you don’t know – template compilation principle
  • “Vue source code learning (three)” you don’t know – first render principle
  • “Vue source code learning (4)” aims to write a study on the principle of computed and Watch that everyone can understand
  • “Vue source code learning (5)” interviewers like to ask — Vue common method source analysis

Or if you are interested in my other vUE source code articles, check out these articles:

  • Vue trivia a week: Do you want to know how Vuex works?
  • A Vue trivia of the week: Do you really know how slots are “inserted”

Code implementation

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 intarget && ! (keyintarget.prototype) || ! ob) { target[key] = valreturn val
    }

    defineReactive(target, key, val)
    return val
}
Copy the code

2.Vue.delete

export default function del (target, key) {
    if (Array.isArray(target)) {
        target.splice(key, 1)
        return
    }

    const ob = target.__ob__

    if(! (keyin target)) return

    delete target[key]

    if(! ob)return

    ob.dep.notify()
}
Copy the code

3.Vue.observable

export default function observable (obj) {
    observable(obj)
    return obj
}
Copy the code

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); // Get parameters
    args.unshift(this); // Add the Vue constructor to the argument

    if (typeof plugin.install === 'function') {
        plugin.install.apply(plugin, args)
    } else if (typeof plugin === 'function') {
        plugin.apply(null, args)
    }

    installedPlugins.push(plugin)
    return this
}
Copy the code

5.nextTick

let callbacks = []; // The callback function
let pending = false;
function flushCallbacks() {
  pending = false; // Return the flag to false
  // Execute the callbacks in turn
  for (let i = 0; i < callbacks.length; i++) { callbacks[i](); }}let timerFunc; // Start with microtasks and implement asynchronous refreshes in a graceful downgrading of priority
if (typeof Promise! = ="undefined") {
  // If promise is supported
  const p = Promise.resolve();
  timerFunc = () = > {
    p.then(flushCallbacks);
  };
} else if (typeofMutationObserver ! = ="undefined") {
  // MutationObserver mainly listens for DOM changes and is also an asynchronous method
  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 (typeofsetImmediate ! = ="undefined") {
  SetImmediate does not support mediate
  timerFunc = () = > {
    setImmediate(flushCallbacks);
  };
} else {
  // Finally demote using setTimeout
  timerFunc = () = > {
    setTimeout(flushCallbacks, 0);
  };
}

export function nextTick(cb) {
  callbacks.push(cb);
  if(! pending) { pending =true; timerFunc(); }}Copy the code

conclusion

One unit!