浅谈Vue.use到底是什么鬼


Posted in Javascript onJanuary 21, 2020

我们在使用Vue做项目开发的时候,看到不少轮子都是通过Vue.use来进行使用,感觉甚是高大上。

不过Vue.use到底是什么鬼?不妨来看个究竟。

其实这些轮子都可以称之为插件,它的功能范围没有严格的限制,一般包含如下几种:

  • 添加全局方法或者属性。如: vue-custom-element
  • 添加全局资源:指令/过滤器/过渡/组件等。如 vue-touch
  • 通过全局混入来添加一些组件选项。如 vue-router
  • 添加 Vue 实例方法,通过把它们添加到 Vue.prototype 上实现。
  • 一个库,提供自己的 API,同时提供上面提到的一个或多个功能。如 vue-router

无论大小,插件要实现的功能无非就是上述这几种。但是,这并不妨碍我们创造出复杂的插件,不过我们还是希望给用户提供一个简单的使用方法,他不需要关注插件内部做了些什么。固Vue提供了use方法,专门来在new Vue()之前使用插件。

不管是官方提供的插件(例如vue-router、vuex),还是第三方的插件(例如ElementUI、ant)都是采用了此方式,不外乎插件内部的功能不同而已。当然,还有其他诸多此类插件,awesome-vue 就集合了大量由社区贡献的插件和库。

接下来,我们就来看下这个神秘的use方法是如何实现的。

Vue.js 的插件应该暴露一个 install 方法。这个方法的第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象,用于传入插件的配置:

MyPlugin.install = function (Vue, options) {
 // 1. 添加全局方法或属性
 Vue.myGlobalMethod = function () {
  // 逻辑...
 }
 // 2. 添加全局资源
 Vue.directive('my-directive', {
  bind (el, binding, vnode, oldVnode) {
   // 逻辑...
  }
  ...
 })
 // 3. 注入组件选项
 Vue.mixin({
  created: function () {
   // 逻辑...
  }
  ...
 })
 // 4. 添加实例方法
 Vue.prototype.$myMethod = function (methodOptions) {
  // 逻辑...
 }
 // 5. 注册全局组件
 Vue.component('myButton',{
  // ...组件选项
 })
}
Vue.use(MyPlugin,{
 // ...options
})

一个插件内部大概就是如上所示,其实也不外乎上述那几种东西,甚是简单??。接下来我们就来看下真实的案例ElementUI:

const components = [ Pagination, Dialog, Autocomplete/* 此处由于篇幅省略若干个组件 */];
const install = function(Vue, opts = {}) {
 locale.use(opts.locale);
 locale.i18n(opts.i18n);
 // 注册全局组件
 components.forEach(component => {
  Vue.component(component.name, component);
 });
 Vue.use(InfiniteScroll);
 Vue.use(Loading.directive);
 // 添加实例方法
 Vue.prototype.$ELEMENT = {
  size: opts.size || '',
  zIndex: opts.zIndex || 2000
 };
 // 添加实例方法
 Vue.prototype.$loading = Loading.service;
 Vue.prototype.$msgbox = MessageBox;
 Vue.prototype.$alert = MessageBox.alert;
 Vue.prototype.$confirm = MessageBox.confirm;
 Vue.prototype.$prompt = MessageBox.prompt;
 Vue.prototype.$notify = Notification;
 Vue.prototype.$message = Message;
};
/* istanbul ignore if */
if (typeof window !== 'undefined' && window.Vue) {
 install(window.Vue);
}
export default {
 version: '2.13.0',
 locale: locale.use,
 i18n: locale.i18n,
 install,
 CollapseTransition,
 Loading,
 Pagination,
 Dialog,
 Autocomplete,
 // ...other components
};

我们不难发现,其实自己来实现一个插件也是超级简单,只要对外暴露一个install方法即可,在使用Vue.use的时候,会调用这个方法。所以我们只要将要实现的内容放到install内部即可。这样的好处就是插件需要一开始调用的方法都封装在install里面,更加精简和可拓展性更高。

大家可能也有注意到,这里的install其实是将所有的组件全部引入了。作为一个庞大的插件库,这样可能会有一些性能问题。用过的ElementUI的同学都知道,它是支持按需引入的,其实在上面的示例中也可以发现一些蛛丝马迹。

const components = [ Pagination, Dialog, Autocomplete/* 此处由于篇幅省略若干个组件 */];
// ....省去中间内容
export default {
 version: '2.13.0',
 locale: locale.use,
 i18n: locale.i18n,
 install,
 CollapseTransition,
 Loading,
 Pagination,
 Dialog,
 Autocomplete,
 // ...other components
};

这里将每个组件都单独都导出了,而在每个组件内部,也类似的暴露了install来组件每个组件,这样就可以单独Vue.use每个组件,从而实现按需引入的目的。

import Alert from './src/main';
/* istanbul ignore next */
Alert.install = function(Vue) {
 Vue.component(Alert.name, Alert);
};
export default Alert;

除了上述内容之外,还有几点值得我们注意一下:

插件传入的如果是一个对象,则执行其install方法,如果是一个函数,则执行它自身,并bind this为null,然后传入额外的参数

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

如果插件没有被注册过,那么注册成功之后会给插件添加一个installed的属性,其值为true。Vue.use方法内部会检测插件的installed属性,从而避免重复注册插件

Vue.use其实并不神秘,内部还是我们平时使用的这些东西,仅仅只是给他们套上了一层高端的外衣而已。我们在开发中,也可以尝试使用这种方式,不仅简单,而且有逼格

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

Javascript 相关文章推荐
JQuery textlimit 显示用户输入的字符数 限制用户输入的字符数
May 14 Javascript
jquery中防刷IP流量软件影响统计的一点对策
Jul 10 Javascript
JavaScript中setInterval的用法总结
Nov 20 Javascript
JavaScript实现动态添加Form表单元素的方法示例
Aug 14 Javascript
Vue.js中关于侦听器(watch)的高级用法示例
May 02 Javascript
JavaScript实现选项卡效果的分析及步骤
Apr 16 Javascript
vue.js基于v-for实现批量渲染 Json数组对象列表数据示例
Aug 03 Javascript
layui加载数据显示loading加载完成loading消失的实例代码
Sep 23 Javascript
24个解决实际问题的ES6代码片段(小结)
Feb 02 Javascript
JS内置对象和Math对象知识点详解
Apr 03 Javascript
在react-antd中弹出层form内容传递给父组件的操作
Oct 24 Javascript
一篇文章弄清楚Ajax请求的五个步骤
Mar 17 Javascript
ant-design-vue 快速避坑指南(推荐)
Jan 21 #Javascript
Ant Design Vue 添加区分中英文的长度校验功能
Jan 21 #Javascript
python虚拟环境 virtualenv的简单使用
Jan 21 #Javascript
详解vue中v-bind:style效果的自定义指令
Jan 21 #Javascript
vue.js iview打包上线后字体图标不显示解决办法
Jan 20 #Javascript
Angular单元测试之事件触发的实现
Jan 20 #Javascript
vue elementui 实现搜索栏公共组件封装的实例代码
Jan 20 #Javascript
You might like
PHP实现的封装验证码类详解
2013/06/18 PHP
显示youtube视频缩略图和Vimeo视频缩略图代码分享
2014/02/13 PHP
PHP构造函数与析构函数用法示例
2016/09/28 PHP
浅谈ThinkPHP中initialize和construct的区别
2017/04/01 PHP
PHP简单实现图片格式转换(jpg转png,gif转png等)
2019/10/30 PHP
HTML5如何适配 iPhone IOS 底部黑条
2021/03/09 HTML / CSS
原创javascript小游戏实现代码
2010/08/19 Javascript
jQuery EasyUI API 中文文档 - TreeGrid 树表格使用介绍
2011/11/21 Javascript
利用百度地图JSAPI生成h7n9禽流感分布图实现代码
2013/04/15 Javascript
jQuery文件上传插件Uploadify使用指南
2014/06/05 Javascript
在JavaScript里防止事件函数高频触发和高频调用的方法
2014/09/06 Javascript
jQuery通过扩展实现抖动效果的方法
2015/03/11 Javascript
asp知识整理笔记3(问答模式)
2015/09/27 Javascript
Javascript实现图片加载从模糊到清晰显示的方法
2016/06/21 Javascript
JS实现控制图片显示大小的方法【图片等比例缩放功能】
2017/02/18 Javascript
浅谈angular2路由预加载策略
2017/10/04 Javascript
解决ie img标签内存泄漏的问题
2017/10/13 Javascript
javascript实现Emrips反质数枚举的示例代码
2017/12/06 Javascript
layui-table表复选框勾选的所有行数据获取的例子
2019/09/13 Javascript
[02:26]2016国际邀请赛8月3日开战 中国军团出征西雅图
2016/08/02 DOTA
跟老齐学Python之有容乃大的list(2)
2014/09/15 Python
Python内置函数dir详解
2015/04/14 Python
在Python的Django框架中编写编译函数
2015/07/20 Python
Python实现简单的文件传输与MySQL备份的脚本分享
2016/01/03 Python
基于Python对象引用、可变性和垃圾回收详解
2017/08/21 Python
Python设计模式之迭代器模式原理与用法实例分析
2019/01/10 Python
python通过txt文件批量安装依赖包的实现步骤
2019/08/13 Python
大学生毕业自我鉴定范文
2013/11/03 职场文书
大四自我鉴定
2014/02/08 职场文书
大学班级干部的自我评价分享
2014/02/10 职场文书
成品库仓管员岗位职责
2014/04/06 职场文书
关于读书的演讲稿400字
2014/08/27 职场文书
民事调解书范文
2015/05/20 职场文书
2015年妇委会工作总结
2015/05/22 职场文书
2015入党个人自传范文
2015/06/26 职场文书
MySQL 执行数据库更新update操作的时候数据库卡死了
2022/05/02 MySQL