zoukankan      html  css  js  c++  java
  • vue.use()方法从源码到使用

    在做 vue 开发的时候大家一定经常接触 Vue.use() 方法,官网给出的解释是: 通过全局方法 Vue.use() 使用插件;我觉得把使用理解成注册更合适一些,首先看下面常见的注册场景。

    1
    2
    3
    4
    5
    6
    7
    8
    import Router from 'vue-router'
    Vue.use(Router)
     
    import Vuex from 'vuex'
    Vue.use(Vuex)
     
    import Echarts from 'echarts'
    Vue.prototype.$echarts = Echarts

    关于 echarts 的注册很简单,直接挂在 Vue 方法的原型上,通过原型链继承的关系可以在任意一个组件里通过 this.$echarts 访问到 echarts 实例,我们来写一个简单的例子证明一下。

    1
    2
    3
    4
    5
    6
    7
    8
    function myVue(title){
     this.title = title
    }
    myVue.prototype.myUse = '在原型上添加公共属性'
    const A = new myVue('我是实例A')
    const B = new myVue('我是实例B')
    console.log(A.title, B.title, A.myVue, B.myVue, )
    // 我是实例A 我是实例B 在原型上添加公共属性 在原型上添加公共属性

    而 Router 和 Vuex 的注册就要去分析 Vue.use() 的源码了,在分析源码之前先总结一下官方对 Vue.use() 方法的说明:

    • 通过全局方法 Vue.use() 使用插件
    • Vue.use 会自动阻止多次注册相同插件
    • 它需要在你调用 new Vue() 启动应用之前完成
    • Vue.use() 方法至少传入一个参数,该参数类型必须是 Object 或 Function,如果是 Object 那么这个 Object 需要定义一个 install 方法,如果是 Function 那么这个函数就被当做 install 方法。在 Vue.use() 执行时 install 会默认执行,当 install 执行时第一个参数就是 Vue,其他参数是 Vue.use() 执行时传入的其他参数。

    官网说 Vue.use() 是用来使用插件的,那么传入的 Router 和 Vuex 就是这里指的插件,而这个插件本质上又是一个 install 方法。至于 install 方法内部实现了什么逻辑就由插件自身的业务决定了。

    vue.use()源码


    下面切入本文的主题。我们知道了vue.use()怎么用还不够,还要知道它的内部是怎么实现的。下面展示源码:

    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()源码中采用了flow的语法。flow语法,官方解释是:

    Flow is a static type checker for your JavaScript code. It does a lot of work to make you more productive. Making you code faster, smarter, more confidently, and to a bigger scale.

    简单的意思就是flow是JavaScript代码的静态类型检查工具。官网链接
    使用flow的好处就是:在编译期对js代码变量做类型检查,缩短调试时间, 减少因类型错误引起的bug。我们都知道js是解释执行语言,运行的时候才检查变量的类型,flow可以在编译阶段就对js进行类型检查。

    下面将对vue.use()源码进行解读:

    1、首先先判断插件plugin是否是对象或者函数:
    Vue.use = function (plugin: Function | Object)

    2、判断vue是否已经注册过这个插件
    installedPlugins.indexOf(plugin) > -1
    如果已经注册过,跳出方法

    3、取vue.use参数。
    const args = toArray(arguments, 1)

    4、toArray()取参数
    代码:

    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
      }

    let i = list.length - start意思是vue.use()方法传入的参数,除第一个参数外(第一个参数是插件plugin),其他参数都存储到一个数组中,并且将vue对象插入到参数数组的第一位。最后参数数组就是[vue,arg1,arg2,...]

    5、判断插件是否有install方法,如果有就执行install()方法。没有就直接把plugin当Install执行。

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

    plugin.install.apply(plugin, args)将install方法绑定在plugin环境中执行,并且传入args参数数组进install方法。此时install方法内的this指向plugin对象。
    plugin.apply(null, args) plugin内的this指向null.

    最后告知vue该插件已经注册过installedPlugins.push(plugin)保证每个插件只会注册一次。

    Vue.use()有什么用

    在 install 里我们可以拿到 Vue 那么和 Vue 相关的周边工作都可以考虑放在 Vue.use() 方法里,比如:

    • directive注册
    • mixin注册
    • filters注册
    • components注册
    • prototype挂载
    • ...

    echarts 用 Vue.use() 来注册

    main.js

    1
    2
    3
    4
    5
    6
    7
    import Vue from 'vue'
    import echarts from './echarts.js'
    Vue.use(echarts)
     
    new Vue({
     ...
    })

    echarts.js

    1
    2
    3
    4
    5
    6
    import Echarts from 'echarts'
    export default {
     install(Vue){
      Vue.prototype.$echarts = Echarts
     }
    }

    这样写的好处是可以在 install 的文件里做更多配置相关的工作,main.js 不会变的臃肿,更方便管理。

    全局组件用 Vue.use() 来注册

    base.js

    1
    2
    3
    4
    5
    6
    7
    8
    import a from './a'
    import b from './b'
    let components = { a, b }
    const installBase = {
     install (Vue) {
      Object.keys(components).map(key => Vue.component(key, components[key]))
     }
    }

    main.js

    1
    2
    3
    4
    5
    6
    7
    import Vue from 'vue'
    import base from './base.js'
    Vue.use(base)
     
    new Vue({
     ...
    })
  • 相关阅读:
    Monkey界面版测试工具
    手游兼容性测试
    周版本制度
    08 | 事务到底是隔离的还是不隔离的?
    jackson
    localDateTime和Date
    服务器被攻击后数据库密码被破解
    GC收集器
    linux安装nginx,设置代理,负载均衡
    微信(公众,商户,开放)平台的区别
  • 原文地址:https://www.cnblogs.com/blueball/p/12504661.html
Copyright © 2011-2022 走看看