vue插件实现

 

 

一: index.js  入口文件  vue-toast.vue 插件组件化    .babelrc babel-loader配置文件   vue-toast-demo.js webpack打包之后的组件,后期直接在index.html中引用即可

二:webpack.config.js 打包组件

var path = require('path');

module.exports = {
entry:
'./src/lib/index.js', // 入口
output: { // path:'./dist', // 指定输出路径 path:path.join(__dirname,'./dist'), // 2.0以后必须是绝对路径 filename: 'vue-toast-demo.js', // 插件的名字 libraryTarget:'umd', // 输出的文件格式,umd可适用各种规范(cmd/amd/commonjs...) library:'VueToastDemo' // 输出的文件库的名字 }, module:{ // module模块;解析一些webpack不认识的文件
// 放加载器 rules:[ { test:/\.vue$/, // 处理vue文件 loader:'vue-loader', exclude:/node_modules/, options:{ // 解析vue文件中一些其他的语法 loaders:{ scss:'style-loader!css-loader!sass-loader' // loader解析从右到左,先用sass-loader处理成css,再用css-loader进行处理,再用style-loader插入到HTML中 } } }, { test:/\.js$/, // 处理js文件 loader:'babel-loader', include:path.join(__dirname,'src'), // 指定目录解析 exclude:/node_modules/ // 过滤掉node_modules文件夹 } ] }, // js文件的合并,HTML的生成,插件等等 plugins:[ ] };

 

三:vue-toast.vue 

<template>
    <section class="toast-container">
        <div class="toast" v-bind:class="[visible?'fade-in':'fade-out']">
            <span>{{message}}</span>
        </div>
    </section>
</template>

<script>
export default{
    data(){
        return {
            message:'',
            visible:false
        }
    }
}
</script>

<style scoped lang="scss">
  <!-- 淡入 -->
    @keyframes fade-in {
        0%   { opacity: 0; transform: scale(0.7);}
        100% { opacity: 1; transform: scale(1);}
    }
  <!-- 淡出 --> @keyframes fade
-out { 0% { opacity: 1; transform: scale(1);} 100% { opacity: 0; transform: scale(0.7);} } .toast-container{ position:absolute; left:0; top:0; bottom:0; right:0; z-index:2000; display:flex; justify-content:center; align-items:center; .toast{ width: 180px; height:60px; line-height: 60px; text-align:center; background-color: rgba(0,0,0,0.6); border-radius:10px; color:white; } .fade-in { animation-name: fade-in; animation-duration: 0.3s; animation-fill-mode: both; } .fade-out { animation-name: fade-out; animation-duration: 0.3s; animation-fill-mode: both; } } </style>

效果图

 

 

四:index.js

// 入口文件
import ToastComponent from './vue-toast.vue'

let Toast = {}
Toast.install = function(Vue,options){   // 必须定义一个install方法,才可以在使用时Vue.use()
    // 默认配置
    var opt = {
        duration:3000
    }

    // 用户配置覆盖默认配置
    for(var key in options){
        opt[key] = options[key];
    }

    // 在vue的原型上面拓展一个$toast函数
    Vue.prototype.$toast = function(message,option){
        let callback = '';
        
        // 配置覆盖,设置局部配置
        if(typeof option == 'object'){
            for(var key in option){
                opt[key] = option[key];
            }
        }else if(typeof option == 'function'){
            callback = option;
        }

        // 用Vue.extend()继承ToastComponent组件,构成一个ToastController实例
        const ToastController = Vue.extend(ToastComponent);

//new ToastController()相当于一个新的Vue对象
        //这个对象挂载到空的div里面,类似于vue组件中 var vm = new Vue({ data:{} ... }).$mount("#app")功能
        var instance = new ToastController().$mount(document.createElement("div"));

        instance.message = message;
        instance.visible = true; //显示插件

        document.body.appendChild(instance.$el);

        setTimeout(()=>{
            instance.visible = false;  //隔ms隐藏插件
            setTimeout(()=>{
                document.body.removeChild(instance.$el); //移除对象
                callback && callback();
            },500)
        }, opt.duration)
    };

    // Vue.prototype.$toast['show'] = function(message,option){
    //      Vue.prototype.$toast(message,option);
    // }
    // Vue.prototype.$toast['success'] = function(message,option){
    //      Vue.prototype.$toast(message,option);
    // }
    // Vue.prototype.$toast['info'] = function(message,option){
    //      Vue.prototype.$toast(message,option);
    // }
    // Vue.prototype.$toast['error'] = function(message,option){
    //      Vue.prototype.$toast(message,option);
    // }

    // 简化上面代码
    ['show','success','info','error'].forEach(function(type){
        Vue.prototype.$toast[type] = function(message,option){
            return Vue.prototype.$toast(message,option);
        }
    });

}

// if(window.Vue){
//     Vue.use(Toast);
// }

if(typeof window !== 'undefined' && window.Vue){
    window.Vue.use(Toast);
}

// 导出
export default Toast;

 

五:index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>Title</title>
    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css">
    <script type="text/javascript" src="../node_modules/vue/dist/vue.js"></script>
    <script type="text/javascript" src="../dist/vue-toast-demo.js"></script>
</head>
<body>
<div id="app" class="text-center">
    <h2>vue-toast for mibile</h2>
    <div class="form-group row">
        <a class="btn btn-primary" href="javascript:;" @click="toast">默认toast</a>
    </div>
    <div class="form-group row">
        <a class="btn btn-info" href="javascript:;" @click="toast2">5秒后关闭toast</a>
    </div>
    <div class="form-group row">
        <a class="btn btn-success" href="javascript:;" @click="toast3">关闭toast后,执行回调</a>
    </div>
</div>
<script type="text/javascript">
    new Vue({
        el:"#app",
        methods:{
            toast:function(){
                this.$toast.show("当前点击了标签");
            },
            toast2:function(){
                this.$toast.show("当前点击了标签",{
                    duration:5000
                });
            },
            toast3:function(){
                this.$toast.show("当前点击了标签",function(){
                    alert("这里是回掉函数")
                });
            }
        }
    })
</script>
</body>
</html>

 

posted @ 2020-03-20 18:05  apple78  阅读(217)  评论(0)    收藏  举报