vuetify是 Vue 的一个UI框架,帮助我们快速搭建应用。提供了 80 多个 Vue.js 组件,这些组件是根据谷歌 Material Design 指南实现的。Vuetify 支持所有平台上的浏览器,包括 IE11 和 Safari 9+(使用 polyfill),并提供了 8 个 vue-cli 模板。官方网站:Vuetify — A Material Design Framework for Vue.js (vuetifyjs.com)

虽然Vuetify为我们提供了这么多优秀的组件,但是去没有类似element 中的message消息提示,实现 成功、警告、消息等函数式的全局消息反馈。

所以,今天我们就用Vuetify的snackbar封装一个全局的、函数式的消息组件。

首先:我们先建立一个 store/modules/message.js文件,管理 snackbar 的变量。

const state = {
    text:'', // 提示文字
    show:false, // 是否显示
    color:'', // 颜色
    closeBtn: true, // 是否显示关闭按钮
    closeBtnType:'icon', // icon or text 关闭按钮的类型
    timeout: 5000, // 自动关闭的时间
    callback: null, // 关闭后的回调
}

let messageTimer = null;

const mutations = {
    SET_MESSAGE: (state, message) => {
        if(messageTimer){
            clearTimeout(messageTimer);
        }
        state = Object.assign(state, message);
        if(state.show && state.timeout > 0){
            // 自动关闭
            messageTimer = setTimeout(()=>{
                state = Object.assign(state, {
                    show:false,
                });
                if(state.callback && typeof state.callback === 'function'){
                    state.callback(state);
                }
            }, state.timeout);
        }
    },
}


const actions = {
    success({commit}, text){
        return new Promise((resolve, reject) => {
            commit('SET_MESSAGE', {
                text:text,
                color:'success',
                show:true,
            });
        })
    },
    error({commit}, text){
        return new Promise((resolve, reject) => {
            commit('SET_MESSAGE', {
                text:text,
                color:'error',
                show:true,
            });
        })
    },
    warning({commit}, text){
        return new Promise((resolve, reject) => {
            commit('SET_MESSAGE', {
                text:text,
                color:'warning',
                show:true,
            });
        })
    },
    info({commit}, text){
        return new Promise((resolve, reject) => {
            commit('SET_MESSAGE', {
                text:text,
                color:'info',
                show:true,
            });
        })
    },
    hide({commit}){
        return new Promise((resolve, reject) => {
            commit('SET_MESSAGE', {
                show:false,
            });
        });
    }
};


export default {
    namespaced: true,
    state,
    mutations,
    actions
}

在vuex的index 中引入这个模块:

import Vue from "vue";
import Vuex from "vuex";
// 放置全局信息
Vue.use(Vuex);

import message from "@/store/modules/message";
export default new Vuex.Store({
  modules: {
    message,
  },
});

建立一个components,位置如下:components/Message.vue

<template>
    <v-snackbar top :color="message.color" v-model="message.show">
        {{ message.text }}
        <template v-slot:action="{ attrs }">
            <v-btn v-if="message.closeBtnType==='text'" text v-bind="attrs" @click="hideMessage">关闭</v-btn>
            <v-btn icon v-else v-bind="attrs" @click="hideMessage"><v-icon>mdi-close-circle</v-icon></v-btn>
        </template>
    </v-snackbar>
</template>
<script>
export default {
    computed:{
        message(){
            return this.$store.getters.message;
        },
    },
    methods:{
        hideMessage(){
            this.$store.dispatch('message/hide');
        },
    }
}
</script>

App.vue中引入Message组件

<template>
  <div id="app">
    <v-app>
      <router-view />
      <message />
    </v-app>
  </div>
</template>
<script>
import Message from '@/components/Message.vue'
export default {
  components:{
    Message
  },
}
</script>

由于vuex的全局属性,所以你可以项目的任意地方调用dispatch来创建消息条的实例:

methods:{
    showMessage(){
    	this.$store.dispatch('message/success','登录成功');
    },
    showError(){
    	this.$store.dispatch('message/error','登录失败');
    },
     showInfo(){
    	this.$store.dispatch('message/info','登录消息');
    },
    ...
  }

这到里,就完封装完成了,当然像全局的loading之类的者可以用上面的方法封装,大家可以试一下,我们一起讨论