当前位置:首页 > 用vue编写一个插件,vue编写一个弹窗插件的原理,vue动态追加element

用vue编写一个插件,vue编写一个弹窗插件的原理,vue动态追加element

发布于 2018-08-29 阅读 365 次 Vue Javascript

原理

这个是从vue官网文档截取的片段,详细可自行阅读官方文档

var MyComponent = Vue.extend({
  template: '<div>Hello!</div>'
})

// 创建并挂载到 #app (会替换 #app)
new MyComponent().$mount('#app')

// 同上
new MyComponent({ el: '#app' })

// 或者,在文档之外渲染并且随后挂载,**后面我们主要用到这个**
var component = new MyComponent().$mount()
document.getElementById('app').appendChild(component.$el)

想法

首先我们先脱离vue,通常我们写一个弹窗(modal模态框)插件会怎么做呢?
有很多种方法,比如:
1、直接写html放在模板文件里,然后通过一个公用的方法配合属性去控制这些模态框,类似bootstrap的做法
2、我们直接写一个公用的js去动态追加模板到body里面,这个模板作为参数传入。

显然第二种方式和原理里面所述相似。

首先,我们创建一个公共的model.js,在这个js里面调用extend来动态创建组件。
下面写出大概代码

function showModel(tempHtml){
    var MyComponent = Vue.extend({
      template: tempHtml
    })
    var model = new MyComponent().$mount();
    document.body.appendChild(model.$el);
}

在外部调用showModel函数即可显示一个弹窗了。

showModel("<div>弹窗提示!!!</div>");

写一个动态的vue弹窗插件最主要的一点就是

var component = new MyComponent().$mount()
document.getElementById('app').appendChild(component.$el)

另外实际应用中需要将showModel挂载到Vue上,还要编写install函数

var $model={};
$model.install = function (Vue, options) {
    Vue.prototype.$model = showModel;
}

还需要调用Vue.use()来装载插件。

Vue.use($model);

使用的时候只需要:

mounted(){
    this.$model('<div>弹窗!!!</div>')
}

下面附上一个完整超级简单的例子:(这个例子哈包含了自己写的一个计算属性的小例子,懒得摘了,凑活看)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
    <style type="text/css">
        .keyboard{width:300px;text-align:center;}
        .keyboard ul{width:300px;overflow:hidden;list-style:none;padding:0;}
        .keyboard li{float:left;width:27%;margin: 3%;background:#ccc;color:#333;border-radius:10px;text-align:center;line-height:50px;}
        .call{display:inline-block;width:97%;line-height:40px;background:#619eea;color:#fff;border-radius:10px;}
        .num{width:100%;line-height:30px;height:30px;font-size:16px;margin-bottom:-10px;overflow:hidden;}
        .num span{float:right;margin-right:3%;}
    </style>
</head>
<body>
    <div class="keyboard" id="app">
        <div class="num"><span @click="delNum()" v-show="number.length">删除</span>{{str}}</div>
        <ul @click="changeNum($event)">
            <li>1</li>
            <li>2</li>
            <li>3</li>
            <li>4</li>
            <li>5</li>
            <li>6</li>
            <li>7</li>
            <li>8</li>
            <li>9</li>
            <li>*</li>
            <li>0</li>
            <li>#</li>
        </ul>
        <div class="call">拨号</div>
    </div>
    <script type="text/javascript">
        var $model={};
        $model.install = function (Vue, options) {
            Vue.prototype.$model = function(tempHtml){
                console.log(tempHtml)
                var MyComponent = Vue.extend({
                  template: tempHtml
                })
                // 这里我们把vue实例挂载到一个新建的div上
                oDiv = document.createElement('div');
                var model = new MyComponent().$mount();
                document.body.appendChild(model.$el);;
            }
        }

        Vue.use($model)

        var app = new Vue({
            el: '#app',
            data: {
                number:[]
            },
            computed:{
                str(){
                    return this.number.join('');
                }
            },
            methods:{
                changeNum($event){
                    if($event.target.nodeName != 'LI'){return;}
                    let n = $event.target.innerHTML;
                    this.number.push(n);
                },
                delNum(){
                    let i = this.number.length-1;
                    i>-1 && this.number.splice(i,1);
                }
            },
            mounted(){
                this.$model('<div>弹窗!!!</div>')
            }
        })
    </script>
</body>
</html>

实际项目中会比较复杂,包括多个弹窗显示的时候蒙层的显示判断,弹窗的大小设置,弹窗的回调函数等等,自己去发掘吧