Vue.use( ) 的核心原理

首先来思考几个问题:

Vue.use是什么?

     vue.use() 是vue提供的一个静态方法,主要是为了注册插件,增加vue的功能。

Vue.use( plugin )

plugin只能是Object 或 Function

vue.use()做了什么工作?

  • 该js如果是对象
    • 该对象里面要有一个install方法
    • Vue.use就是调用里面的install方法
  • 该js是一个function
    • Vue.use时function会直接执行
  • 作用
    • 可以在Vue的原型加一些东西
    • 注册全局组件等
  • 使用
    • 将hellow注册为全局组件
    • 在原型中添加$num= 123

1、在components中新建components.js

import HelloWorld from '@/components/HelloWorld.vue'
export default {
  install: function (Vue) {
    // 这里的Vue就是你调用install方法时传递过来的
    // 可以在Vue原型中加一些东西
    Vue.prototype.$num = 123
    // 注册全局组件
    Vue.component(HelloWorld.name, HelloWorld)
  }
}

2、在main.js中调用

import App from './App.vue'
import components from '@/assets/components.js'
Vue.use(components)
Vue.config.productionTip = false

new Vue({
  render: h => h(App)
}).$mount('#app')

3、Helloworld.vue

<template>
  <div>
    <h1>这里是HelloWord</h1>
    <h2>{{ $num }}</h2>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld'
}
</script>

<style></style>
  • 该js为对象时,component.js写法不一样,其他均一样

Vue.use(VueRouter)就是这么实现的

export default function (Vue) {
  Vue.component(HelloWorld.name, HelloWorld)
  Vue.prototype.$num = 123
}

function install (Vue) {
    if (install.installed && _Vue === Vue) { return }
    install.installed = true;

    _Vue = Vue;

    var isDef = function (v) { return v !== undefined; };

    var registerInstance = function (vm, callVal) {
      var i = vm.$options._parentVnode;
      if (isDef(i) && isDef(i = i.data) && isDef(i = i.registerRouteInstance)) {
        i(vm, callVal);
      }
    };

    Vue.mixin({
      beforeCreate: function beforeCreate () {
        if (isDef(this.$options.router)) {
          this._routerRoot = this;
          this._router = this.$options.router;
          this._router.init(this);
          Vue.util.defineReactive(this, '_route', this._router.history.current);
        } else {
          this._routerRoot = (this.$parent && this.$parent._routerRoot) || this;
        }
        registerInstance(this, this);
      },
      destroyed: function destroyed () {
        registerInstance(this);
      }
    });

    Object.defineProperty(Vue.prototype, '$router', {
      get: function get () { return this._routerRoot._router }
    });

    Object.defineProperty(Vue.prototype, '$route', {
      get: function get () { return this._routerRoot._route }
    });

    Vue.component('RouterView', View);
    Vue.component('RouterLink', Link);

    var strats = Vue.config.optionMergeStrategies;
    // use the same hook merging strategy for route hooks
    strats.beforeRouteEnter = strats.beforeRouteLeave = strats.beforeRouteUpdate = strats.created;
  }
Object.defineProperty(Vue.prototype, '$router', {
  get: function get () { return this._routerRoot._router }
});

Object.defineProperty(Vue.prototype, '$route', {
  get: function get () { return this._routerRoot._route }
});

其核心就是以上两行代码在install方法中将$router和route挂载到Vue原型上

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

在Vue中引入使用第三方库通常我们都会采用import的形式引入进来,但是有的组件在引入之后又做了Vue.use()操作,有的组件引入进来又进行了Vue.prototype.$something = something,那么它们之间有什么联系呢?

 先说一下vue.prototype,  在vue项目中通常我们引入axios来进行请求接口数据,通过pnpm 安装axios之后我们只需要在文件中导入improt axios from ‘axios’就可以使用,有时候我们会加上一句vue.prototype.$axios=axios

Vue.prototype.axios=axios,其实是在vue的原型上增加了一个axios,通过在全局注册这个方法,然后在周后的文件中都可以通过$axios直接来使用axios

Vue.use() 的源码中的逻辑

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

在源码中首先限制了它传入的值的类型只能是Function或者Object,然后判断了该插件是不是已经注册过,防止重复注册,然后调用了该插件的install方法,源码中也有介绍到Vue.use()可以接受多个参数的,除第一个参数之后的参数我们都是以参数的形式传入到当前组件中。

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值