美文网首页前端之美-VueJs
五、撸vue/cli 3.+ 的正确姿势(共用弹出、全局弹出框

五、撸vue/cli 3.+ 的正确姿势(共用弹出、全局弹出框

作者: Baby_ed6e | 来源:发表于2019-04-26 17:05 被阅读0次

    1、element ui 和ant-design-vue ui 基本没有全局弹出框

    1.为什么这么说呢?比如element ui 很多全局的弹出框都是使用指令的形式,element 和ant-design-vue也都是本页的弹出框,但是真要实现全局的弹出框,感觉根本没有。

    2.拿最简单的例子,如果半小时没有访问页面,token过期了,这时候需要用户点击访问某个按钮或者链接的时候,在当前页面弹出个登录框,而不是直接跳转到登录页面!

    3.再比如,如果没有指令形式的全局loding,我们如何让每次访问api的时候,能够全局loading显示隐藏?尽管loading使用指令很好用,但是道理想通,利用这些组件我没没法随心所欲的做一个全局的弹出。

    4.在js文件中,js文件并非组件.vue文件,不能让<template>内的原生显示隐藏,这是一个死角,只能使用指令形式。

    5.如果我们采用ant-design-vue ,我们不可能每个页面都搞一个弹出框,这有点不现实。而且效率不高。

    以下来自element一个message弹出框指令。显然这样绑定很费力,而且里面的数据不能在下一个页面使用。

    this.$message({
          dangerouslyUseHTMLString: true,
          message: '<strong>这是 <i>HTML</i> 片段</strong>'
    });
    

    2、使用vuex插件管理store,然后全场任意位置控制全局自定义弹出(360度无死角)

    用vuex管理弹出框显示隐藏状态,上store代码,内容并不多。


    store结构

    modules文件夹下的app.js

    const app = {
        state: {
            loading: false,
            loginDialog: false
        },
        mutations: {
            SET_LOADING: (state, loading) => {
                state.loading = loading;
            },
            SET_LOGINDIALOG: (state, loginDialog) => {
                state.loginDialog = loginDialog;
            }
        },
        actions: {
            setLoading({ commit }, loading) {
                commit("SET_LOADING", loading);
            },
            setLoginDialog({ commit }, loginDialog) {
                commit("SET_LOGINDIALOG", loginDialog);
            }
        }
    };
    export default app;
    

    getters.js

    import store from "@/store/index";
    const getters = {
        loading: state => state.app.loading,
        loginDialog: state => state.app.loginDialog
    }
    export default getters;
    

    store中的index.js

    import Vue from "vue";
    import Vuex from "vuex";
    import getters from "./getters";
    import app from "./modules/app";
    
    Vue.use(Vuex);
    
    const store = new Vuex.Store({
        modules: {
            app
        },
        getters
    });
    export default store;
    

    根目录的main.js 引入

    import Vue from "vue";
    import App from "./App.vue";
    import router from "./router/index";
    import store from "./store/index";    // 状态管理
    
    Vue.config.productionTip = false;
    new Vue({
        router,
        store,
        render: h => h(App)
    }).$mount("#app");
    

    state里定义了两个状态,全局的loading,全局的登录弹出状态,至于下面的mutations、actions、getters.js 等等直接查看vuex官网概念。


    主菜:修改app.vue

    <template>
        <div id="app">
            // 使用了ant-design-vue 的loading组件
            <a-spin :spinning="$store.getters.loading" class="page-loading">
                <router-view />
            </a-spin>
            //  使用了 ant-design-vue 的本页弹出组件,当然我们也可以使用div封装一个
            <a-modal
                v-model="$store.getters.loginDialog"
                title="请登录"
                :closable="false"
                onOk="handleOk"
                :footer="null"
            >
                <my-login @login="handleLogin"> </my-login>
            </a-modal>
        </div>
    </template>
    

    这里组件直接绑定了 &store.getters.loading 就可以

    360度无死角发起弹出
    在任意一个js文件中,例如在request.js中,发现请求出现 401、403, 可能token过期了,弹出登录框

    import store from "@/store/index";
    // 调用全局弹出框
    store.dispatch("setLoginDialog", true);
    // 调用全局loading
    store.dispatch("setLoading", true);
    

    在任意vue文件里的script中

    this.$store.dispatch("setLoginDialog", false);
    

    3、总结

    1.解决了某些情况在js文件里必须使用指令才能发起弹出的壁垒,真正实现无死角,
    2.统一管理公用的弹出框,更省心省力,更加直观。
    3.摆脱指令,表单内容在其它页面不会消失,全局公用

    相关文章

      网友评论

        本文标题:五、撸vue/cli 3.+ 的正确姿势(共用弹出、全局弹出框

        本文链接:https://www.haomeiwen.com/subject/radqnqtx.html