vue插件编写与实战

上图不上种,菊花万人捅:

关于

金沙官网线上 1

前言

热爱vue开发的同学肯定知道awesome-vue 这个github地址,里面包含了数以千计的vue开源插件,而这些插件大都来自第三方开发者们,是他们为vue社区提供了大量的技术支持和解决方案。本文立足vue开源的理念,主要为vue开发者讲解编写vue插件的方法和步骤,通过理论与实践相结合的方式来加深大家对vue插件编写的认识。

loading.js:

vue插件介绍

import './loading.css'

let Loading = {}
// 避免重复install,设立flag
Loading.installed = false
Loading.install = function (Vue) {
  if (Loading.installed) return
  Vue.prototype.$loading = {}
  Vue.prototype.$loading.show = () => {
    // 如果页面有loading则不继续执行
    if (document.querySelector('#vue-loading')) return
    // 1、创建构造器,定义loading模板
    let LoadingTip = Vue.extend({
      template: `<div id="vue-loading">
                    <div class="loader"></div>
                  </div>`
    })
    // 2、创建实例,挂载到文档以后的地方
    let tpl = new LoadingTip().$mount().$el
    // 3、把创建的实例添加到body中
    document.body.appendChild(tpl)
    // 阻止遮罩滑动
    document.querySelector('#vue-loading').addEventListener('touchmove', function (e) {
      e.stopPropagation()
      e.preventDefault()
    })
    Loading.installed = true
  }
  Vue.prototype.$loading.hide = () => {
    let tpl = document.querySelector('#vue-loading')
    document.body.removeChild(tpl)
  }
}

export default Loading

1. 插件与组件

金沙官网线上,在讲解插件之前,我们首先来了解下vue插件和组件的关系,在我们的vue项目中我们使用组件的频率往往会大于插件,关系如下图所示:

金沙官网线上 2

在没有封装组件之前,如果不使用第三方插件,那么很多情况下我们会编写几个常用的组件来提供给页面使用,如Alert/Loading组件,而你可能需要在很多页面中引入并且通过components注册组件,但是像这样使用率很高的组件一般我们希望全局注册后直接就可以在相应页面使用,因此我们需要将他们封装成插件,比如像vux这样的ui组件库,即提供了组件功能也提供了某些全局注册的插件。

用一句话简单概括两者的关系就是:插件可以封装组件,组件可以暴露数据给插件。

  loading.css:

2. 插件分类

金沙官网线上 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中。

#vue-loading {
  width: 100%;
  height: 100%;
  position: absolute;
  left: 0;
  top: 0
}

.loader {
  position: relative;
  width: 2.5em;
  height: 2.5em;
  transform: rotate(165deg);
}

.loader:before, .loader:after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  display: block;
  width: 0.5em;
  height: 0.5em;
  border-radius: 0.25em;
  transform: translate(-50%, -50%);
}

.loader:before {
  animation: before 2s infinite;
}

.loader:after {
  animation: after 2s infinite;
}

@keyframes before {
  0% {
    width: 0.5em;
    box-shadow: 1em -0.5em rgba(225, 20, 98, 0.75), -1em 0.5em rgba(111, 202, 220, 0.75);
  }
  35% {
    width: 2.5em;
    box-shadow: 0 -0.5em rgba(225, 20, 98, 0.75), 0 0.5em rgba(111, 202, 220, 0.75);
  }
  70% {
    width: 0.5em;
    box-shadow: -1em -0.5em rgba(225, 20, 98, 0.75), 1em 0.5em rgba(111, 202, 220, 0.75);
  }
  100% {
    box-shadow: 1em -0.5em rgba(225, 20, 98, 0.75), -1em 0.5em rgba(111, 202, 220, 0.75);
  }
}

@keyframes after {
  0% {
    height: 0.5em;
    box-shadow: 0.5em 1em rgba(61, 184, 143, 0.75), -0.5em -1em rgba(233, 169, 32, 0.75);
  }
  35% {
    height: 2.5em;
    box-shadow: 0.5em 0 rgba(61, 184, 143, 0.75), -0.5em 0 rgba(233, 169, 32, 0.75);
  }
  70% {
    height: 0.5em;
    box-shadow: 0.5em -1em rgba(61, 184, 143, 0.75), -0.5em 1em rgba(233, 169, 32, 0.75);
  }
  100% {
    box-shadow: 0.5em 1em rgba(61, 184, 143, 0.75), -0.5em -1em rgba(233, 169, 32, 0.75);
  }
}

/**
 * Attempt to center the whole thing!
 */
html,
body {
  height: 100%;
}

.loader {
  position: absolute;
  top: calc(50% - 1.25em);
  left: calc(50% - 1.25em);
}

3. 插件使用

在plugins.js中我们仅仅编写了一个插件的空壳子,假如现在需要全局注册该插件,我们可以在入口文件,比如main.js中注册:

...

import Vue from 'vue'
import MyPlugin from './plugins/plugins.js'

Vue.use(MyPlugin);

...

通过全局方法 Vue.use() 即可使用该插件,其自动会调用install方法。Vue.use会自动阻止注册相同插件多次,届时只会注册一次该插件。

  在main.js里面 :

vue插件编写方法

上述我们提到了编写插件的4种方法,接下来我们对其一一进行讲解:

   import Vue from 'vue';
   import Loading from '@/components/loading'
   Vue.use(Loading)

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自定义指令

本文由金沙官网线上发布于Web前端,转载请注明出处:vue插件编写与实战

您可能还会对下面的文章感兴趣: