Message组件的调用方式 #

<template>
    <button @click="showMessage">点我啊</button>
</template>
<script>
export default {
    methods:{
        showMessage(){
            Message.info({ // 直接调用
                content:'hello 我帅不帅',
                duration:3000
            });
            this.$message.info({ // 通过实例调用
                content:'hello 你很帅',
                duration:3000
            })
        }
    }
}
</script>

编写Message组件 #

要考虑数据驱动视图,多次点击显示多个弹层,给每个层增加 id号,延迟时间和内容

<template>
    <div class="messages">
        <!-- 显示在数组中的层 -->
        <div v-for="message in messages" :key="message.id">
            {{message.content}}
        </div>
    </div>
</template>
<script>
export default {
    data(){
        return {messages:[]}
    },
    mounted(){
        // 给所有弹层增加唯一标示 方便弹层的卸载
        this.id = 0;
    },
    methods:{
        add(option){
            let id = this.id++; // id号
            let layer = {...option,id}
            this.messages.push(layer); // 将层存储起来
            layer.timer = setTimeout(()=>{
                this.remove(layer);
            },option.duration)
        },
        remove(layer){
            clearTimeout(layer.timer); // 清除定时器
            // 移除层 
            this.messages = this.messages.filter(message=>layer.id !== message.id);
        }
    }
}   
</script>

通过js文件控制显示Message弹层 #

import Vue from 'vue';
import MessageComponent from './Message.vue';
let getInstance = () =>{
    let vm = new Vue({
        render:h=>h(MessageComponent)
    }).$mount();
    let messageComponent = vm.$children[0];
    // 获取真实dom元素,将其挂在页面上
    document.body.appendChild(vm.$el);
    return {
        add(options){ // 调用组件的add方法
            messageComponent.add(options);
        }
    }
}
const Message = {
    info(options){
        // 调用增加弹层方法
        getInstance().add(options);
    },
    warn(){},
    danger(){},
    success(){}
}
// 暴露 不同类型的弹层方法
export {
    Message
}
let instance;
let inst = () => {
    instance = instance || getInstance();
    return instance;
}
const Message = {
    info(options){
        // 调用增加弹层方法
        inst().add(options);
    },
    warn(){},
    danger(){},
    success(){}
}
// 暴露 不同类型的弹层方法
export {
    Message
}

封装插件 #

install方法和use方法的应用

let _Vue;
export default {
    install(Vue,options){
        if(!_Vue){
            _Vue = Vue;
            let $message = {}
            Object.keys(Message).forEach(type => {
                $message[type] = Message[type]
            });
            Vue.prototype.$message = $message
        }
    }
}
// 组件中使用插件
import {Message} from './components/Message';
this.$message.info({
        content:'hello 你很帅',
        duration:3000
})

Minx方法可以注入数据 #

给每个组件增加公用属性

Vue.mixin({
    beforeCreate() {
        if(this.$options.info){
            // 把数据挂在自己的_info上
            this._info = this.$options.info;
        }else{
            this._info = this.$parent && this.$parent._info;
        }
    },
})