如何开发一个移动web UI组件库:vue插件篇

@youngwind 2016-08-11 07:28:32发表于 youngwind/blog Vue移动H5

问题由来

继上一篇 #80 ,本篇着重讨论vue插件在组件库中的作用。
对于toast组件,如果我采取跟button这些普通UI组件一样的方式的话,会存在一些问题。
假设这样一个调用场景:页面当中有一个按钮,点击按钮弹toast,toast的内容和回调函数均可自定义。
调用toast组件的伪代码如下

// example.html
<div id='#app'>
    <button v-on:click='showToastA'></button>
    <toast :show.sync="toast.show">
    {{toast.content}}
    </toast>
</div>
// example.js
new Vue({
    el: '#app',
    data: {
        toast:{
            show: false,
            content:"Toast A内容"
        }
    },
    method:{
        showToastA:function(){
            this.toast.show = true;
        },
        onShowToast:function(){
            // 显示Toast A     
        },
        onHideToast:function(){
            // 隐藏Toast A
        }
    },
   watch: {
       toast: function(val){
            if(val.show){
                 this.onShowToast();
            } else {
                 this.onHideToast();
            }
       }
  }
})

问题在于:我只是想点击的时候弹出toast而已,为什么需要我一开始就在html和js中定义这个toast的内容和回调?很多时候我都无法预知什么时候会出现toast,比如我很可能在一个ajax的回调里面调用toast。更为关键的是假如有两个按钮呢?如果他们的内容和回调函数都不一样呢?难道我需要在html中实例化两个toast,在js中定义四个function?太麻烦了!
显然,如果编写toast组件仍然采取普通的组件方式,会导致很多的问题。
在探讨合适的toast组件编写方式之前,我们先来看看我们想象当中的调用方式应该是怎么样的。

我想要的

从jquery时代过来的人,可能会很熟悉这样的写法:

$.toast.show({
    content: '显示内容',
    onShow:function(){
         // 显示回调函数
    },
    onHide: function(){
        // 隐藏回调函数
    }
})

没错。虽然现在已经是组件化通行的时代了。但是,对于toast这种东西,上面的写法依然是更为优雅的调用方式。所以,我们来看看如何在vue组件化中实现这样的调用方式。

Vue插件机制

我在碰到这个难题的时候,正好vux的作者也在做这样的改良,查看他写的代码,我发现其实是使用了vue的插件机制

模(抄)仿(袭)着大牛的代码,很快我也写完了toast插件。下面说一下我的理解。

vue插件是一个全局性的东西,在vue model第一次初始化的时候就会执行里面的install方法,并且只会执行一次。如下图所示,页面刚刚初始化完成之后,其实toast插件就已经在DOM元素当中了,只不过没有显示出来而已。之后无论我们调用show还是hide方法,不过是修改这个实例的数据和回调方法。回调函数什么时候执行呢?是由watch监听show字段来决定调用时机的。
2016-08-11 3_54_41

遗留问题:
之前一直在用vue-touch,现在才发现原来这也属于vue插件。之后有时间研究一下如何用vue插件编写自定义指令。