浅谈Vue.use的使用


Posted in Javascript onAugust 29, 2018

vue.use(plugin, arguments) 语法

参数:plugin(Function | Object)

用法:

如果vue安装的组件类型必须为Function或者是Object

如果是个对象,必须提供install方法

如果是一个函数,会被直接当作install函数执行

install函数接受参数,默认第一个参数为Vue,其后参数为注册组件时传入的arguments

先举个?

我们先来看一个简单的事例

首先我使用官方脚手架新建一个项目vue init webpack vue-demo

然后我创建两个文件index.js plugins.js.

我将这两个文件放置在src/classes/vue-use目录下

接下来对这两个文件进行编写

// 文件: src/classes/vue-use/plugins.js

const Plugin1 = {
  install(a, b, c) {
    console.log('Plugin1 第一个参数:', a);
    console.log('Plugin1 第二个参数:', b);
    console.log('Plugin1 第三个参数:', c);
  },
};

function Plugin2(a, b, c) {
  console.log('Plugin2 第一个参数:', a);
  console.log('Plugin2 第二个参数:', b);
  console.log('Plugin2 第三个参数:', c);
}

export { Plugin1, Plugin2 };
// 文件: src/classes/vue-use/index.js

import Vue from 'vue';

import { Plugin1, Plugin2 } from './plugins';

Vue.use(Plugin1, '参数1', '参数2');
Vue.use(Plugin2, '参数A', '参数B');

然后我们在入口文件main.js引用这段代码

// 文件: src/main.js

import Vue from 'vue';

import '@/classes/vue-use';
import App from './App';
import router from './router';

Vue.config.productionTip = false;

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  render: h => h(App),
});

此时我们执行npm run dev打开8080端口开启开发调试工具可以看到控制台输出以下信息

浅谈Vue.use的使用

...]

从中可以发现我们在plugin1中的install方法编写的三个console都打印出来,第一个打印出来的是Vue对象,第二个跟第三个是我们传入的两个参数。

而plugin2没有install方法,它本身就是一个方法,也能打印三个参数,第一个是Vue对象,第二个跟第三个也是我们传入的两个参数。

那么现在我们是不是大概对Vue.use有一个模糊的猜想~

分析源码

好我们还是不要猜想,直接上源码

// 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首先判断这个插件是否被注册过,不允许重复注册。

并且接收的plugin参数的限制是Function | Object两种类型。

对于这两种类型有不同的处理。

首先将我们传入的参数整理成数组 => const args = toArray(arguments, 1)。

(toArray源码)

// Vue源码文件路径:src/core/shared/util.js

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
}

再将Vue对象添加到这个数组的起始位置args.unshift(this),这里的this 指向Vue对象

如果我们传入的plugin(Vue.use的第一个参数)的install是一个方法。也就是说如果我们传入一个对象,对象中包含install方法,那么我们就调用这个plugin的install方法并将整理好的数组当成参数传入install方法中。 => plugin.install.apply(plugin, args)
如果我们传入的plugin就是一个函数,那么我们就直接调用这个函数并将整理好的数组当成参数传入。 => plugin.apply(null, args)
之后给这个插件添加至已经添加过的插件数组中,标示已经注册过 => installedPlugins.push(plugin)
最后返回Vue对象。

小结

通过以上分析我们可以知道,在我们以后编写插件的时候可以有两种方式。

一种是将这个插件的逻辑封装成一个对象最后将最后在install编写业务代码暴露给Vue对象。这样做的好处是可以添加任意参数在这个对象上方便将install函数封装得更加精简,可拓展性也比较高。

还有一种则是将所有逻辑都编写成一个函数暴露给Vue。

其实两种方法原理都一样,无非第二种就是将这个插件直接当成install函数来处理。

个人觉得第一种方式比较合理。

举个?

export const Plugin = {
  install(Vue) {
    Vue.component...
    Vue.mixins...
    Vue...
    // 我们也可以在install里面执行其他函数,Vue会将this指向我们的插件
    console.log(this) // {install: ...,utils: ...}
    this.utils(Vue)  // 执行utils函数
    console.log(this.COUNT) // 0
  },
  utils(Vue) {
    Vue...
    console.log(Vue) // Vue
  },
  COUNT: 0  
}
// 我们可以在这个对象上添加参数,最终Vue只会执行install方法,而其他方法可以作为封装install方法的辅助函数

const test = 'test'
export function Plugin2(Vue) {
  Vue...
  console.log(test) // 'test'
  // 注意如果插件编写成函数形式,那么Vue只会把this指向null,并不会指向这个函数
  console.log(this) // null
}
// 这种方式我们只能在一个函数中编写插件逻辑,可封装性就不是那么强了

小弟不才,对vue源码的理解暂且到这。欢迎大佬们多指教~

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript针对网页节点的增删改查用法实例
Feb 02 Javascript
javascript判断移动端访问设备并解析对应CSS的方法
Feb 05 Javascript
js实现鼠标经过时图片滚动停止的方法
Feb 16 Javascript
JS模拟并美化的表单控件完整实例
Aug 19 Javascript
基于css3新属性transform及原生js实现鼠标拖动3d立方体旋转
Jun 12 Javascript
实例详解display:none与visible:hidden的区别
Mar 30 Javascript
ES6新特性七:数组的扩充详解
Apr 21 Javascript
解决layer 动态加载select 失效的问题
Sep 18 Javascript
VUE 组件转换为微信小程序组件的方法
Nov 06 Javascript
使用vue重构资讯页面的实例代码解析
Nov 26 Javascript
vant 自定义 van-dropdown-item的用法
Aug 05 Javascript
多种类型jQuery网页验证码插件代码实例
Jan 09 jQuery
微信小程序支付前端源码
Aug 29 #Javascript
微信小程序使用swiper组件实现类3D轮播图
Aug 29 #Javascript
javascript中UMD规范的代码推演
Aug 29 #Javascript
详解webpack自定义loader初探
Aug 29 #Javascript
在vue中使用SockJS实现webSocket通信的过程
Aug 29 #Javascript
微信小程序自定义select下拉选项框组件的实现代码
Aug 28 #Javascript
微信小程序中上传图片并进行压缩的实现代码
Aug 28 #Javascript
You might like
百事可乐也出咖啡了 双倍咖啡因双倍快乐
2021/03/03 咖啡文化
PHP如何编写易读的代码
2007/07/10 PHP
PHP文件读写操作之文件写入代码
2011/01/13 PHP
PHP函数getenv简介和使用实例
2014/05/12 PHP
Laravel 5.5官方推荐的Nginx配置学习教程
2017/10/06 PHP
Js+Dhtml:WEB程序员简易开发工具包(预先体验版)
2006/11/07 Javascript
设置iframe的document.designMode后仅Firefox中其body.innerHTML为br
2012/02/27 Javascript
jquery动态改变onclick属性导致失效的问题解决方法
2013/12/04 Javascript
Node.js中require的工作原理浅析
2014/06/24 Javascript
浅析javascript操作 cookie对象
2014/12/26 Javascript
jQuery学习笔记之jQuery+CSS3的浏览器兼容性
2015/01/19 Javascript
javascript实现数字倒计时特效
2016/03/30 Javascript
详解JSON1:使用TSQL查询数据和更新JSON数据
2016/11/21 Javascript
JS复制对应id的内容到粘贴板(Ctrl+C效果)
2017/01/23 Javascript
提高Web性能的前端优化技巧总结
2017/02/27 Javascript
JQuery form表单提交前验证单选框是否选中、删除记录时验证经验总结(整理)
2017/06/09 jQuery
jQuery选择器特殊字符与属性空格问题
2017/08/14 jQuery
canvas+gif.js打造自己的数字雨头像的示例代码
2017/10/26 Javascript
vue 实现的树形菜的实例代码
2018/03/19 Javascript
浅谈vue父子组件怎么传值
2018/07/21 Javascript
解决vue A对象赋值给B对象,修改B属性会影响到A的问题
2018/09/25 Javascript
mui js控制开关状态、修改switch开关的值方法
2019/09/03 Javascript
[02:20]2014DOTA2西雅图邀请赛 MVP外卡赛首胜采访
2014/07/09 DOTA
netbeans7安装python插件的方法图解
2013/12/24 Python
简单介绍Python中的try和finally和with方法
2015/05/05 Python
对Python3中列表乘以某一个数的示例详解
2019/07/20 Python
Python爬虫设置ip代理过程解析
2020/07/20 Python
Python中实现一行拆多行和多行并一行的示例代码
2020/09/06 Python
使用scrapy ImagesPipeline爬取图片资源的示例代码
2020/09/28 Python
英国打印机墨水和碳粉商店:Printerinks
2017/06/30 全球购物
世界上最全面的草药补充剂和顶级品牌维生素网站:HerbsPro
2019/01/20 全球购物
巴西购物网站:Submarino
2020/01/19 全球购物
几个常见的消息中间件(MOM)
2014/01/08 面试题
夫妻分居协议书范本(有子女版)
2014/11/01 职场文书
公司员工培训管理制度
2015/08/04 职场文书
MySQL系列之九 mysql查询缓存及索引
2021/07/02 MySQL