关于javascript:美团面试官有了解过-Vueuse-是怎么实现的吗

27次阅读

共计 1834 个字符,预计需要花费 5 分钟才能阅读完成。

这个 api 是做什么的

看源码之前,先去看看官网文档的阐明,这样更容易了解。依据 Vue 官网文档的阐明,这个 api 用于装置 Vue.js 插件。如果插件是一个对象,必须提供 install 办法。如果插件是一个函数,它会被作为 install 办法。install 办法调用时,会将 Vue 作为参数传入。

Vue.use(plugin); // 入参类型 Object | Function

此外文档中还提到:

  • 该办法须要在调用 new Vue() 之前被调用;
  • 当 install 办法被同一个插件屡次调用,插件将只会被装置一次;

源码剖析

Vue.use 的源码不到 20 行,在这个目录下:

node_modules\vue\src\core\global-api\use.js

源码的内容如下:

import {toArray} from '../util/index'

export function initUse (Vue: GlobalAPI) {Vue.use = function (plugin: Function | Object) {const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
    if (installedPlugins.indexOf(plugin) > -1) {return this}

    // additional parameters
    const args = toArray(arguments, 1)
    args.unshift(this)
    if (typeof plugin.install === 'function') {plugin.install.apply(plugin, args)
    } else if (typeof plugin === 'function') {plugin.apply(null, args)
    }
    installedPlugins.push(plugin)
    return this
  }
}

从源码能够看出,Vue.use 接管的 plugin 类型是 Function | Object,这与文档的形容统一。

接着在上面的代码中,this._installedPlugins 用于记录已装置的插件,而后判断传入的 plugin 是否已装置,如果已装置就不再装置,这也在文档中提到了。顺便提一下,判断插件是否已装置,这边用的是 indexOf 办法,其实是在向下兼容,因为 includes 是 ES2016 语法。

const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
if (installedPlugins.indexOf(plugin) > -1) {return this}

而后上面是这段代码:

const args = toArray(arguments, 1)

其中用到了 toArray 办法,定义在

node_modules\vue\src\shared\util.js:218

toArray 函数的作用是将类数组对象转为数组(在这里是 arguments 对象),而后第二个参数代表起始下标,这里传 1 也就是疏忽数组的第一个元素(也就是 plugin),从以上代码咱们能够推断出,Vue.use 大略是这么用的:

Vue.use(plugin, arg1, arg2...)

接着上面的代码将 Vue(这里的 this 指向 Vue)增加到数组的最后面:

args.unshift(this)

最初失去的 args 应该会相似于:

[Vue, arg1, arg2...]

而后就是装置插件。如果 plugin 自身是对象,外面提供了 install 办法,那就间接调用这个 install 办法,而后传入 args。因为咱们在 args 后面增加了 Vue,所以 Vue 会作为第一个参数被传入,这与文档中形容的 install 办法能获取到 Vue 统一。如果 plugin 自身是函数,那就间接调用这个函数装置插件。

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

再就是记录一下已装置的插件,避免反复装置:

installedPlugins.push(plugin)

最初一步返回 Vue,以便进行链式调用:

return this

参考

Vue.use(plugin) – Vue 官网文档

正文完
 0