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({ ...}) |
vue.use()方法从源码到使用的更多相关文章
- Vue.js 2.0源码解析之前端渲染篇
一.前言 Vue.js框架是目前比较火的MVVM框架之一,简单易上手的学习曲线,友好的官方文档,配套的构建工具,让Vue.js在2016大放异彩,大有赶超React之势.前不久Vue.js 2.0正式 ...
- 如何实现全屏遮罩(附Vue.extend和el-message源码学习)
[Vue]如何实现全屏遮罩(附Vue.extend和el-message源码学习) 在做个人项目的时候需要做一个类似于电子相册浏览的控件,实现过程中首先要实现全局遮罩,结合自己的思路并阅读了(饿了么) ...
- Scala 深入浅出实战经典 第41讲:List继承体系实现内幕和方法操作源码揭秘
Scala 深入浅出实战经典 第41讲:List继承体系实现内幕和方法操作源码揭秘 package com.parllay.scala.dataset /** * Created by richard ...
- [Java源码解析] -- String类的compareTo(String otherString)方法的源码解析
String类下的compareTo(String otherString)方法的源码解析 一. 前言 近日研究了一下String类的一些方法, 通过查看源码, 对一些常用的方法也有了更透彻的认识, ...
- Pycharm中查看方法的源码
方法1.鼠标放在函数上,Ctrl+B,看源码 方法2.将光标移动至要查看的方法处,按住ctrl 键,点击鼠标左键,即可查看该方法的源码.
- 如何查看laravel门脸类包含方法的源码
以Route门脸类为例,我们定义路由时使用的就是Route门脸类,例如我们在web.php中定义的路由 use Illuminate\Support\Facades\Route; Route::get ...
- 《JAVA高并发编程详解》-Thread start方法的源码
Thread start方法的源码:
- HttpServlet中service方法的源码解读
前言 最近在看<Head First Servlet & JSP>这本书, 对servlet有了更加深入的理解.今天就来写一篇博客,谈一谈Servlet中一个重要的方法-- ...
- vue UI库iview源码解析(2)
上篇问题 在上篇<iview源码解析(1)>中的index.js 入口文件的源码中有一段代码有点疑惑: /** * 在浏览器环境下默认加载组件 */ // auto install if ...
随机推荐
- sudo: 在加载插件“sudoers_policy”时在 /etc/sudo.conf 第 0 行出错 sudo: /usr/lib/sudo/sudoers.so 必须只对其所有者可写 sudo: 致命错误,无法加载插件
解决办法: su root chmod 644 /usr/lib/sudo/sudoers.so chown -R root /usr/lib/sudo 千万不要给 /usr 赋全部权限!!! ...
- PHP 把MYSQL重复ID 二维数组重组为三维数组
应用场景 MYSQL在使用关联查询时,比如 产品表 与 产品图片表关联,一个产品多张产品图片,关联查询结果如下: $arr=[['id'=>1,'img'=>'img1'],['id'=& ...
- JAVA企业级应用TOMCAT实战(三)
JVM优化涉及到两大方面我个人的理解 .如何分配JVM的内存空间 .我应该使用什么垃圾回收器 JVM产生的垃圾需要回收.回收有不同的回收器. JVM的调优需要了解各个垃圾回收机制的原理. 终极目标:降 ...
- 【DNS域名解析命令】 dig
dig - DNS lookup utility dig 命令主要用来从 DNS 域名服务器查询主机地址信息. Dig (domain information groper 域名信息搜索)是一个灵活的 ...
- Ansible 配置文件详解
# config file for ansible -- http://ansible.com/ # ============================================== # ...
- Process Synchronization-Example 1
问题描述 把学生和监考老师都看作进程,学生有N人,教师1人.考场门口每次只能进出一个人,进考场原则是先来先进.当N个学生都进入考场后,教师才能发卷子.学生交卷后可以离开考场,教师要等收上来全部卷子并封 ...
- Codeforces Round #622 (Div. 2) 1313 B Different Rules
B. Different Rules Nikolay has only recently started in competitive programming, but already qualifi ...
- 题解 AT3849 【[ABC084C] Special Trains】
本文为UserUnknown原创 题目大意 总共有 \(N\) 个车站,每两个相邻的车站有单向的车. 从第 \(i\) 个站到第 \(i+1\) 个站 需要时间 \(C_i\) 分钟,且第一趟车在 \ ...
- Jenkins 项目构建
一:新建项目 (1)点击新建,输入项目名称--构建一个自由风格的软件项目,点击ok (2)构建触发器-----设置每两分钟执行一次 其中有5个参数 (*****) 第一个是代表分钟 一小时内的分钟数 ...
- centos7 源码安装nginx
1. 安装编译所需要的工具包 yum -y install gcc-c++ pcre pcre-devel zlib zlib-devel openssl openssl-devel 2. 安装ngi ...