专栏首页Node.js开发如何开发一个Vue插件

如何开发一个Vue插件

今天带着大家开发个简单的Vue消息框插件,需求如下:

请使用Vue实现一个自定义 alert 弹框组件。要求:

1、弹框组件可打开和关闭 。

2、 将弹框组件扩展为 Vue 插件,通过 API 的方式进行调用,插件API的调用规则为 vm.$alert('提示消息') 。

3. 开发环境使用普通的 HTML 页面,直接通过 script 标签引用 vue.js 即可。

熟悉Vue的开发者,应该能够看出来这里的需求其实可以拆分成两个,第一个需求是完成一个弹窗组件,并且这个组件能够打开和关闭,第二个需求是将这个组件扩展为插件。

这道题目要求在开发环境中使用普通的 HTML 页面,直接通过 script 标签引用 vue.js 即可,开发一个弹窗组件代码如下:

    // 用Vue.extend生成组件构造函数
    let AlertConstructor =Vue.extend({
            template: '<div class="dialog-content" v-show="xian">{{msg}}</div>',
            data:function(){
                return {
                    xian:false,
                    msg:"自定义信息"
                }
            },
            methods: {
                show:function(msg){
                    this.xian = true
                    this.msg = msg;
                },
                hide:function(){
                    this.xian = false
                }
            }
        })
    // 组件实例化,生成dom但是不渲染;
    let instance = new AlertConstructor().$mount();

上面代码首先用Vue.extend方法生成一个组件,或者叫组件构造器,然后将其实例化,但是组件在实例化的时候通常会传递一个el来挂载Vnode。

但是我们在生成这个组件实例时不想其渲染到页面,我们需要用dom操作的方式将其插入页面,所以在其实例化时没有传递el参数,而是调用$mount方法,这个方法可以传递一个参数,参数为要挂载的el,也可以不传递参数,不传递参数时只生成dom但是不渲染。

下面就将考虑如何将这个组件扩展成插件,我们来看一下vue的官方文档的示例代码:

// 调用 `MyPlugin.install(Vue)`
Vue.use(MyPlugin)

new Vue({
  //... options
})

Vue.use(MyPlugin, { someOption: true })

通过上面的代码我们可以看出,如果在Vue中使用插件需要用Vue.use方法加载插件,加载插件的原理就是调用插件的install方法,可以看出插件的形式为一个对象,这个对象上有一个install方法,而install方法的第一个参数为Vue构造函数,由此得出我们封装插件的逻辑应该都在install方法中。

看一下官方封装插件的示例伪代码:

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) {
    // 逻辑...
  }
}

按照上面代码,实现将组件扩展为插件的代码如下:

var MyAlert = {
      install: function (Vue, options) {
        let AlertConstructor = Vue.extend({
          template: '<div class="dialog-content" v-show="xian">{{msg}}</div>',
          data: function () {
            return {
              xian: false,
              msg: "自定义信息"
            }
          },
          methods: {
            show: function (msg) {
              this.xian = true
              this.msg = msg;
            },
            hide: function () {
              this.xian = false
            }
          }
        })
        // 组件实例化,生成dom但是不渲染;
        let instance = new AlertConstructor().$mount();
        // 在组件原型上添加$show显示方法
        Vue.prototype.$show = function (msg) {
          instance.show(msg)
        };
        // 在组件原型上添加$hide隐藏方法
        Vue.prototype.$hide = function (msg) {
          instance.show(msg)
        };
        // 将生成的组件实例dom插入body中。
        document.body.appendChild(instance.$el);
      }
    }

完整测试代码如下:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <!-- 1. 导入Vue的包 -->
  <script src="./lib/vue-2.4.0.js"></script>
  <style>
    /* 组件样式 */
    .dialog-content {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translateY(-50%);
      transform: translateX(-50%);
    }

    .none {
      display: none
    }
</style>
</head>

<body>
  <div id="app">
    <p>hello world</p>
  </div>

  <script>
    // =================开发插件开始================================
    var MyAlert = {
      install: function (Vue, options) {
        let AlertConstructor = Vue.extend({
          template: '<div class="dialog-content" v-show="xian">{{msg}}</div>',
          data: function () {
            return {
              xian: false,
              msg: "自定义信息"
            }
          },
          methods: {
            show: function (msg) {
              this.xian = true
              this.msg = msg;
            },
            hide: function () {
              this.xian = false
            }
          }
        })
        // 组件实例化,生成dom但是不渲染;
        let instance = new AlertConstructor().$mount();
        // 在组件原型上添加$show显示方法
        Vue.prototype.$show = function (msg) {
          instance.show(msg)
        };
        // 在组件原型上添加$hide隐藏方法
        Vue.prototype.$hide = function (msg) {
          instance.show(msg)
        };
        // 将生成的组件实例dom插入body中。
        document.body.appendChild(instance.$el);
      }
    }
    ///========================开发插件结束======================================/ 
    Vue.use(MyAlert);
    new Vue({
      el: "#app",
      mounted () {
      //注册插件后可以使用$show方法开启消息框并传递参数
        this.$show("123");
        setTimeout(()=>{
        //调用hide方法关闭弹窗
          this.$hide()
        },2000)
      }
    })
</script>
</body>
</html>

下面我们来总结一下开发Vue插件的思路:

1、首先定义一个插件对象,对象必须有一个install方法。

2、在insall方法中通过参数访问Vue构造函数,直接在其原型上添加方法。

3、定义一个组件类,并且实现两个方法,关闭和显示

4、将组件类实例化,并且调用$mount生成dom

5、将组件实例化生成的dom插入到body。

组件开发完成后,要想调用组件,只需要用Vue.use方法调用一下即可。

本文分享自微信公众号 - nodejs全栈开发(geekclass),作者:挥刀北上

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-03-06

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • javascript数组去重的N种方法

    这段代码使用了循环嵌套,首先循环遍历数组中每一项,然后用每一项和当前项后面的数组元素比对,相同的话,将其从数组中删除,依次循环完成,达到去重目的。

    挥刀北上
  • 一道火车票排序的面试题

    面试题是这样描述的,一个人从北京出发,坐火车去旅行,途经N个城市,目的地是上海,拿到这些火车票如何对其进行排序。

    挥刀北上
  • javascript数组拍平的两种方法

    下面笔者将为大家演示一下,将一个多维数组拍平成一个一维数组的两种方法,算是抛砖引玉,大家有更好的方法可以在留言区发表。

    挥刀北上
  • 【追求极致】我是如何把easy级别的算法题做成hard级别的。

    2、如果你懂某些算法思想,这道题很简单,如果不懂,那么这道题顿时很难,例如有些需要dp来处理的。

    帅地
  • 小述JavaScript数组的增删改查

    操作数组一直以来都是很头疼的问题,特别是我这样的比较菜的码农,我个人是很排斥数组这个东西的,但是很多的时候不用数组还是不行的,毕竟很多的数据只靠一个变量是远远不...

    何处锦绣不灰堆
  • 数组中的方法

    河湾欢儿
  • 前端面试题解密:经典算法之冒泡算法(ES6版)及优化

    随着前端的飞速发展,前端业务开发给前端工程师提出了更高的要求,因而算法题也越来越高频次的出现在前端面试中。有很多的小伙伴找胡哥苦诉,在前端实际开发中(除了涉及游...

    胡哥有话说
  • JS中的数组方法

    注:箭头函数中无法改变this指向,因此如果想用thisValue参数必须使用function函数

    我不是费圆
  • Kafka Producer 异步发送消息居然也会阻塞?

    Kafka 一直以来都以高吞吐量的特性而家喻户晓,就在上周,在一个性能监控项目中,需要使用到 Kafka 传输海量消息,在这过程中遇到了一个 Kafka Pro...

    张乘辉
  • 20180930_ARTS_week14

    想到这个的思路是因为解的过程中,发现如果遇到左边的,需要存起来,后面可能有用(类似入栈),遇到右边的,需要比对前一个值,并且比完如果匹配就没用了(这类似出栈)。...

    Bob.Chen

扫码关注云+社区

领取腾讯云代金券