The article was first published on my blog

Vue provides a global API to register the plug-in. Use to understand its internal implementation, whether it is to see the source code of the plug-in, or to write their own plug-in, will be much easier.

Vue. Use usage

Vue provides a global API for vue. use to register plug-ins such as vuex, vue-Router, etc

usage

Vue.use(plugin)

  • If the argument is an object, the install method must be provided
  • If the argument is a function, it is treated as an install method by itself, and vue is passed in as the argument when the method is called
  • After the vue.use (plugin) call, the plugin’s install method accepts the first parameter by default, which is Vue

This method needs to be called before new vue().

Vue.use automatically prevents the same plug-in from being registered multiple times, even if it is called multiple times.

Vue.use source code analysis

We can start from the source analysis, based on vue 2.6.11 version, the source address is: SRC /core/global-api/use.js

export function initUse (Vue: GlobalAPI) {
  / / to accept a plugin parameters, limit of Function | Object two types
  Vue.use = function (plugin: Function | Object) {
    // _installedPlugins store all registered plugins
    const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
    // Save an array of registered components. If it does not exist, create it. If it does exist, return it directly
    if (installedPlugins.indexOf(plugin) > - 1) {
      return this
    }

    // additional parameters
    // Convert the passed argument to an array
    const args = toArray(arguments.1)
    // Concatenate the Vue object to the array header
    args.unshift(this)
    // If the install method is provided, it is called directly
    if (typeof plugin.install === 'function') {
      // If the component is an object and the install method is provided, call the Install method to pass in the array of parameters and change the 'this' pointer to the component
      plugin.install.apply(plugin, args)
    } else if (typeof plugin === 'function') {
      // Otherwise, execute directly
      plugin.apply(null, args)
    }
    // Store plugin to installedPlugins to indicate that y is registered
    installedPlugins.push(plugin)
    return this}}Copy the code
/** * Convert an Array-like object to a real Array. */
export function toArray (list: any, start? : number) :Array<any> {
  start = start || 0
  let i = list.length - start
  const ret: Array<any> = new Array(i)
  while (i--) {
    ret[i] = list[i + start]
  }
  return ret
}
Copy the code

Vue.use does two main things

  1. Check that the plug-in has been registered so that it does not need to be registered again

  2. If not, call the install method of the plug-in (if the argument is an object, call the install method of the object, if it is a function, call it directly as install method) and pass Vue as the first argument

Vue – the Router in the install

Based on vue-Router3.1.6, source code location: SRC /install.js

import View from './components/view'
import Link from './components/link'

/* export a Vue reference that does not want to be packaged as a dependency package, but does want to use some of the methods provided by Vue, */
export let _Vue

Use Specifies the install method to be exposed during plug-in installation
export function install (Vue) {
  // Check whether it has been installed
  if (install.installed && _Vue === Vue) return
  install.installed = true

  _Vue = Vue

  const isDef = v= >v ! = =undefined

  const registerInstance = (vm, callVal) = > {
    let i = vm.$options._parentVnode
    if (isDef(i) && isDef(i = i.data) && isDef(i = i.registerRouteInstance)) {
      i(vm, callVal)
    }
  }
  / / with beforeCreate
  Vue.mixin({
    beforeCreate () {
      // If router exists on option, it is the root component
      if (isDef(this.$options.router)) {
        this._routerRoot = this
        // The _router attribute of the root component is the router passed in by new Vue
        this._router = this.$options.router
        // Execute init
        this._router.init(this)
        // Make this._router.history.current responsive by using defineReactive, the underlying of which is Object.defineProperty
        Vue.util.defineReactive(this.'_route'.this._router.history.current)
      } else {
        // If the component is not the root component, then recursively look up until the root component is found.
        this._routerRoot = (this.$parent && this.$parent._routerRoot) || this
      }
      registerInstance(this.this)
    },
    destroyed () {
      registerInstance(this)}})Prototype $router = $route; prototype $router = $route

  // Set the proxy to access this.$router directly to this. _routerroot._router
  Object.defineProperty(Vue.prototype, '$router', {
    get () { return this._routerRoot._router }
  })
  // Set the proxy to access this.$route directly to this. _routerroot._route
  Object.defineProperty(Vue.prototype, '$route', {
    get () { return this._routerRoot._route }
  })

  // Register router-view and router-link components
  Vue.component('RouterView', View)
  Vue.component('RouterLink', Link)

  const strats = Vue.config.optionMergeStrategies
  // use the same hook merging strategy for route hooks
  strats.beforeRouteEnter = strats.beforeRouteLeave = strats.beforeRouteUpdate = strats.created
}
Copy the code

The install method in vue-Router does the following:

  1. If the root component is mixin, set _router to this.$options.router

  2. If it’s not the root component, recursively look up until you find the root component, using the _routerRoot tag

  3. Prototype defines $router and $route attributes so that all Vue instances (components) can access the $router and $route attributes

  4. Register the

    ,

    components

reference

  • Vue official documentation – plug-ins
  • Introduction to front-end routing and implementation principle of VUe-Router
  • Vue. Use (plugins), rounding

other

Recently, WE launched a 100-day front-end advanced plan, which is mainly to dig into the principle behind each knowledge point. Welcome to follow the wechat public account “Mucode star”, and we will study together and punch the clock for 100 days.