vue插件介绍
1. 插件与组件
在讲解插件之前,我们首先来了解下vue插件和组件的关系,在我们的vue项目中我们使用组件的频率往往会大于插件,关系如下图所示
2. 插件前置工作
1. 插件内 component 需要带name属性, 例如
export default { name: 'test-panel', // 这里需要注意下,我们是采用的全局注入我们的组件,所以在后面因为我们的组件后,会直接使用这个命名的标签 data () { return { checkedNumber: '' } }, }
2. 打包的项目清单配置文件:
修改webpack.config.js的打包名称
3. 插件分类
vue插件的编写方法一般分为4类,如上图所示。主要注册与绑定机制如下:
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中。
4. 插件使用
在plugins.js中我们仅仅编写了一个插件的空壳子,假如现在需要全局注册该插件,我们可以在入口文件,比如main.js中注册:
... import Vue from 'vue' import MyPlugin from './plugins/plugins.js' Vue.use(MyPlugin); ...
通过全局方法 Vue.use() 即可使用该插件,其自动会调用install方法。Vue.use会自动阻止注册相同插件多次,届时只会注册一次该插件。
vue插件编写方法
上述我们提到了编写插件的4种方法,接下来我们对其一一进行讲解:
1. 添加全局方法或属性
export default { install(Vue, options) { Vue.$myName = '劳卜'; } }
在install方法中,我们直接在Vue实例上声明了$myName属性并进行了赋值,当该插件注册后只要存在Vue实例的地方你都可以获取到Vue.$myName的值,因为其直接绑定在了Vue实例上。
2. 添加全局资源
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自定义指令
3. 添加全局mixin方法
export default { install(Vue, options) { Vue.mixin({ methods: { greetingFn() { console.log('greeting'); } } }); }, }
mixin代表混合的意思,我们可以全局注册一个混合,其会影响注册之后创建的每个 Vue 实例,上方代码注册后会在每个组件实例中添加greetingFn方法,在单文件组件中可以直接通过this.greetingFn()调用。当然如果实例中存在同名方法,则mixin方法中创建的会被覆盖,同时mixin对象中的钩子将在组件自身钩子之前调用。
4. 添加实例方法
export default { install(Vue, options) { Vue.prototype.$myName = '劳卜'; Vue.prototype.showMyName = value => { console.log(value); }; }, }
添加实例方法是最常用的一种方法,其直接绑定在vue的原型链上,我们可以回想一下 JS 里的类的概念。实例方法可以在组件内部,通过this.$myMethod来调用。
5. 插件封装组件
上方4点只讲解了插件自身的4中编写方法,并没有涉及组件的内容,如果我们要在组件的基础上编写插件,我们可以使用Vue.extend(component)来进行,可以见下方loading插件实例。
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对象中才能在页面中使用
下面我们便来封装一下该组件
// 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实例,并挂载到一个div元素上。最后我们需要通过document.body.appendChild($vm.$el)将其插入到DOM节点中。
当我们创建了$vm实例后,我们可以访问该实例的属性和方法,比如通过$vm.show就可以改变loading组件的show值来控制其显示隐藏。
最终我们通过Vue.mixin或者Vue.prototype.$loading来全局添加了$loading事件,其又包含了show和hide两个方法。我们可以直接在页面中使用this.$loading.show()来显示加载,使用this.$loading.hide()来关闭加载。
插件发布
插件编写完后我们的目的除了本地引用注册外,可能更希望发布到线上供他人或其他项目使用,因此我们需要了解插件发布的方法。
1. 发布准备
在发布插件前你需要一个npm账号,你可以访问:https://www.npmjs.com/ 进行注册
2. 发布命令
npm login cd 目录 npm publish