热爱vue开发的同窗确定知道awesome-vue 这个github地址,里面包含了数以千计的vue开源插件,而这些插件大都来自第三方开发者们,是他们为vue社区提供了大量的技术支持和解决方案。本文立足vue开源的理念,主要为vue开发者讲解编写vue插件的方法和步骤,经过理论与实践相结合的方式来加深你们对vue插件编写的认识。html
在讲解插件以前,咱们首先来了解下vue插件和组件的关系,在咱们的vue项目中咱们使用组件的频率每每会大于插件,关系以下图所示:vue
插件与组件node
在没有封装组件以前,若是不使用第三方插件,那么不少状况下咱们会编写几个经常使用的组件来提供给页面使用,如Alert/Loading组件,而你可能须要在不少页面中引入而且经过components注册组件,可是像这样使用率很高的组件通常咱们但愿全局注册后直接就能够在相应页面使用,所以咱们须要将他们封装成插件,好比像vux这样的ui组件库,即提供了组件功能也提供了某些全局注册的插件。git
用一句话简单归纳二者的关系就是:插件能够封装组件,组件能够暴露数据给插件。es6
插件分类github
vue插件的编写方法通常分为4类,如上图所示。主要注册与绑定机制以下:vuex
export default {
install(Vue, options) {
Vue.myGlobalMethod = function () { // 1. 添加全局方法或属性,如: vue-custom-element
// 逻辑...
}
Vue.directive('my-directive', { // 2. 添加全局资源:指令/过滤器/过渡等,如 vue-touch
bind (el, binding, vnode, oldVnode) {
// 逻辑...
}
...
})
Vue.mixin({
created: function () { // 3. 经过全局 mixin方法添加一些组件选项,如: vuex
// 逻辑...
}
...
})
Vue.prototype.$myMethod = function (options) { // 4. 添加实例方法,经过把它们添加到 Vue.prototype 上实现
// 逻辑...
}
}
}复制代码
复制代码
上方代码使用了es6部分语法列出了4种编写插件的方法,而install是注册插件主要调用的方法,包含了两个参数(Vue实例和自定义配置属性options),咱们能够将以上代码存储到plugins.js中。npm
在plugins.js中咱们仅仅编写了一个插件的空壳子,假如如今须要全局注册该插件,咱们能够在入口文件,好比main.js中注册:json
...
import Vue from 'vue'
import MyPlugin from './plugins/plugins.js'
Vue.use(MyPlugin);
...复制代码
复制代码
经过全局方法 Vue.use() 便可使用该插件,其自动会调用install方法。Vue.use会自动阻止注册相同插件屡次,届时只会注册一次该插件。app
上述咱们提到了编写插件的4种方法,接下来咱们对其一一进行讲解:
export default {
install(Vue, options) {
Vue.$myName = '劳卜';
}
}复制代码
复制代码
在install方法中,咱们直接在Vue实例上声明了myName的值,由于其直接绑定在了Vue实例上。
export default {
install(Vue, options) {
Vue.directive('focus', {
bind: function() {},
// 当绑定元素插入到 DOM 中。
inserted: function(el, binding, vnode, oldVnode) {
// 聚焦元素
el.focus();
},
update: function() {},
componentUpdated: function() {},
unbind: function() {}
});
},
}复制代码
复制代码
添加全局资源包含了添加全局的指令/过滤器/过渡等,上方代码咱们经过Vue.directive()添加了一个全局指令v-focus,其主要包含了5种方法,其中inserted表明当绑定元素插入到 DOM 中执行,而el.focus()表明聚焦绑定的元素,这样若是咱们在一个input输入框上绑定该指令就会自动进行focus聚焦。
其余directive提供的方法及用途能够参考:vue自定义指令
export default {
install(Vue, options) {
Vue.mixin({
methods: {
greetingFn() {
console.log('greeting');
}
}
});
},
}复制代码
复制代码
mixin表明混合的意思,咱们能够全局注册一个混合,其会影响注册以后建立的每一个 Vue 实例,上方代码注册后会在每一个组件实例中添加greetingFn方法,在单文件组件中能够直接经过this.greetingFn()调用。固然若是实例中存在同名方法,则mixin方法中建立的会被覆盖,同时mixin对象中的钩子将在组件自身钩子以前调用。
export default {
install(Vue, options) {
Vue.prototype.$myName = '劳卜';
Vue.prototype.showMyName = value => {
console.log(value);
};
},
}复制代码
复制代码
添加实例方法是最经常使用的一种方法,其直接绑定在vue的原型链上,咱们能够回想一下 JS 里的类的概念。实例方法能够在组件内部,经过this.$myMethod来调用。
上方4点只讲解了插件自身的4中编写方法,并无涉及组件的内容,若是咱们要在组件的基础上编写插件,咱们可使用Vue.extend(component)来进行,能够见下方loading插件实例。
<!-- loading.vue组件 -->
<template>
<div class="loading-box" v-show="show">
<div class="loading-mask"></div>
<div class="loading-content">
<div class="animate">
</div>
<div class="text">{{text}}</div>
</div>
</div>
</template>
<script>
export default {
props: {
show: Boolean,
text: {
type: String,
default: '正在加载中...'
},
}
}
</script>复制代码
复制代码
以上是一个loading.vue组件,省略了样式部分,在没有封装插件以前,咱们只能经过import引入并注册到components对象中才能在页面中使用,如:
<template>
<div>
<loading :show="true"></loading>
</div>
</template>
<script>
import Loading from './loading.vue'
export default {
...
components: {
Loading
}
...
}
</script>复制代码
复制代码
下面咱们便来封装一下该组件:
// loading.js
import LoadingComponent from '../components/loading.vue'
let $vm
export default {
install(Vue, options) {
if (!$vm) {
const LoadingPlugin = Vue.extend(LoadingComponent);
$vm = new LoadingPlugin({
el: document.createElement('div')
});
document.body.appendChild($vm.$el);
}
$vm.show = false;
let loading = {
show(text) {
$vm.show = true;
$vm.text = text;
},
hide() {
$vm.show = false;
}
};
if (!Vue.$loading) {
Vue.$loading = loading;
}
// Vue.prototype.$loading = Vue.$loading;
Vue.mixin({
created() {
this.$loading = Vue.$loading;
}
})
}
}复制代码
复制代码
以上咱们新建一个loading.js文件,引入咱们的loading.vue组件,而后经过Vue.extend()方法建立了一个构造器LoadingPlugin,其次咱们再经过new LoadingPlugin()建立了vm.$el)将其插入到DOM节点中。
当咱们建立了vm.show就能够改变loading组件的show值来控制其显示隐藏。
最终咱们经过Vue.mixin或者Vue.prototype.loading事件,其又包含了show和hide两个方法。咱们能够直接在页面中使用this.
loading.hide()来关闭加载。
插件编写完后咱们的目的除了本地引用注册外,可能更但愿发布到线上供他人或其余项目使用,所以咱们须要了解插件发布的方法。
在发布插件前你须要一个npm帐号,你能够访问:www.npmjs.com/ 进行注册
npm login
cd 目录
npm publish复制代码
复制代码
拥有帐号后,你须要在控制台输入npm login命令来登陆你的帐号,而且输入邮箱地址。而后打开你的插件目录,容许npm publish发布。最简单的一个插件目录以下:
├── lib // 插件源码
│ ├── components // 组件目录
│ │ └── loading.vue // 组件文件
│ └── index.js // 插件入口文件
├── index.js // 入口文件
└── package.json // 包管理文件复制代码
复制代码
你能够在项目中安装刚刚的loading插件来进行参考,我已经发布至npm:
npm install super-loading --save复制代码
复制代码
本文的最终目的并非教你们如何去编写一个loading插件,而是帮助你们了解在编写插件的过程当中所使用的技巧和方法,只有掌握了技巧和方法才能写出各类各样的插件,正所谓水到天然渠成。