移动开发框架使用

1、spriteFrame.js

requirejs.onError = function (err) {
    console.log(err.requireType);
    console.log('modules: ' + err.requireModules);
};

(function(require) {
    //require路径配置
    var requireConfig = {
        paths: {
            jquery: SERVER_PATH + '/bower_components/jquery/dist/jquery.min',
            vue: SERVER_PATH + '/bower_components/vue2/vue.min',
            vueRouter: SERVER_PATH + '/bower_components/vue2/vue-router.min',
            text: SERVER_PATH + '/bower_components/text/text',
            util: 'public/util/util',
            MINT: SERVER_PATH + '/fe_components/mobile/MINT/index',
            axios: SERVER_PATH + '/bower_components/vue2/axios.min',
            'emap-mobile': SERVER_PATH + '/fe_components/mobile/emap-mobile.min',
            BH_MOBILE: SERVER_PATH + '/fe_components/mobile/BH_MIXIN_SDK',
            selectRoleIndex: '../../swpubapp/public/mob/component/selectrole/selectrole',
            home: '../../swpubapp/public/mob/component/home/home',
            spriteUtils: '../../swpubapp/public/mob/js/spriteUtil',
            publicVueComponent: '../../swpubapp/public/mob/component',
            'draggable': SERVER_PATH + "/bower_components/vuedraggable/vuedraggable",
            'sortable': SERVER_PATH + "/bower_components/sortable/1.5.1/Sortable.min",
            emapMin: '../../swpubapp/public/mob/js/emapMin',
            pagelog: SERVER_PATH + '/fe_components/sentry/sentry.min',
            cropper: SERVER_PATH + '/bower_components/cropper/cropper.min'
        },
        shim: {
            'emap-mobile': {
                deps: ['jquery'],
            },
            'emapMin': {
                deps: ['jquery'],
            },
            'pagelog': {
                deps: ['jquery']
            }
        },
        waitSeconds: 0

    };

    /**
     * appLoadAsync用于控制app页面的加载方式
     * true: app的所有页面为异步加载,只在使用到时加载
     * false: app的所有页面在应用初始化时一次性加载
     */
    window.appLoadAsync = false;

    //默认的组件库和公共方法以及公共页面
    var requir_default_arr = ['jquery', 'vue', 'vueRouter', 'MINT', 'emap-mobile', 'axios', 'spriteUtils', 'draggable', 'emapMin', 'pagelog', 'cropper'];

    //封装的公共vue组件
    var default_component_arr = [{
        name: 'auditProcess',
        jsPath: 'publicVueComponent/auditprocess/auditProcess'
    }, {
        name: 'noneDatas',
        jsPath: 'publicVueComponent/nonedatas/nonedatas'
    }];

    /**
     * 用于保存所有模块的全局对象:
     * defaultModules:默认的组件库和公共方法以及公共页面
     * pageModules:当前应用的所有页面模块
     * defaultComponents:封装的公共vue组件
     */
    window.REQUIRE_MODULES_ARR = {
        defaultModules: requir_default_arr,
        pageModules: [],
        defaultComponents: default_component_arr
    };

    //配置require
    require.config(requireConfig);

    //加载框架所需的库和公共页面
    require(requir_default_arr, function($, Vue, VueRouter, mintUI, EMAP_MOBILE, axios, sprite, draggable, emapMin) {
        /**
         * 用于解决ios 微信虚拟键盘弹出使得页面乱窜的问题
         */
        $(document).on("blur", "input,select,textarea", function() {
            setTimeout(function() {
                const scrollHeight = document.documentElement.scrollTop || document.body.scrollTop || 0;
                window.scrollTo(0, Math.max(scrollHeight - 1, 0));
            }, 100);
        });
        //设置拖拽组件
        Vue.component('draggable', draggable);

        //将各个组件库输出到全局作用域
        window.axios = axios;
        window.Vue = Vue;
        window.VueRouter = VueRouter;
        window.mintUI = mintUI;
        window.EMAP_MOBILE = EMAP_MOBILE;
        window.WIS_EMAP_SERV = emapMin;

        //vue路由组件
        Vue.use(VueRouter);
        //饿了么移动端组件mint-ui
        Vue.use(mintUI);
        //EMAP相关vue组件
        Vue.use(EMAP_MOBILE);

        //ids认证
        if (userId != null && userId != undefined) {
            //获取角色配置相关参数 --> 获取用户授权功能 --> 初始化应用
            sprite.getSelRoleConfig().then(sprite.getAuthConfig).then(sprite.initApp);
        }
        //游客
        else {
            // 初始化应用--游客模式
            sprite.initApp_visitor();
        }

    });

}(require));

2、对于非游客模式需要ids认证→获取角色配置相关参数 →获取用户授权功能→初始化应用

  • sprite.getSelRoleConfig():获取角色配置参数
  • sprite.getAuthConfig():自定义的模块加载路径在pageRegister.xml中配置,通过getAuthConfig中/sys/swpubapp/MobileCommon/getMenuInfo.do从后台获取配置文件信息,解析成json格式返回给browser
  • sprite.initApp():完成前两步,初始化app

       if (userId != null && userId != undefined) {
            //获取角色配置相关参数 --> 获取用户授权功能 --> 初始化应用
            sprite.getSelRoleConfig().then(sprite.getAuthConfig).then(sprite.initApp);
        }

  •         /**
             * 判断是否进入角色选择页
             * 如果用户有且只有一个角色,直接渲染该角色有权限的页面,否则进入角色选择页面
             */
            getSelRoleConfig: function() {
                var dfd = $.Deferred();
                MOB_UTIL.doPost({
                    url: WIS_CONFIG.ROOT_PATH + '/sys/swpubapp/MobileCommon/getSelRoleConfig.do',
                    params: {
                        APPID: WIS_CONFIG.APPID,
                        APPNAME: WIS_CONFIG.APPNAME
                    }
                }).done(function(result) {
                    window.IS_NEED_SELECTROLE = result.data.IS_NEED_SELECTROLE;
                    //无需选择角色
                    if (IS_NEED_SELECTROLE === "0") {
                        roleId = result.data.DEFAULT_ROLEID;
                    }
                    dfd.resolve();
                });
                return dfd;
            },
    /**
             * 获取用户授权的页面、按钮
             */
            getAuthConfig: function(fromSelectRole) {
               
                var dfd = $.Deferred();
                // IS_NEED_SELECTROLE为1,即需要先选择角色
                // 如果url中含有recallUrl参数,表示访问的是问卷调查,不需要进行角色选择
                if (!fromSelectRole && window.IS_NEED_SELECTROLE == "1" &&
                    (window.location.hash.indexOf('recallUrl') == '-1' && window.location.search.indexOf('recallUrl') == '-1')) {
                    window.REQUIRE_MODULES_ARR.pageModules = [{
                        vueJsPath: 'selectRoleIndex'
                    }];
                    dfd.resolve();
                } else {
                    //这里在后台去调用查询问卷调查的接口
                    MOB_UTIL.doPost({
                        url: WIS_CONFIG.ROOT_PATH + '/sys/swpubapp/MobileCommon/getMenuInfo.do',
                        params: {
                            APPID: WIS_CONFIG.APPID,
                            APPNAME: WIS_CONFIG.APPNAME
                        }
                    }).done(function(result) {
                        //如果发现有问卷需要答,则跳转问卷的地址
                        if (result.data.NEED_QUESTIONNAIRE) {
                            //这个参数用于标记即将跳转问卷调查地址,无需再做后续的路由解析工作
                            window.IS_QUESTIONNAIRE = true;
                            //这边替换新的地址
                            window.location.replace(window.WIS_CONFIG.HOST_PATH + result.data.REDIRECT_URL);
                            dfd.resolve();
                        }
                        //授权按钮列表
                        window.MOBILE_BUTTONAUTH_LIST = result.data.BUTTON;
                        //授权页面列表
                        window.REQUIRE_MODULES_ARR.pageModules = result.data.PAGES;
                        dfd.resolve();
                    });
                }
                return dfd;
            }

     

3、spriteUtil.js  -----→sprite.initApp 

 //初始化应用
initApp: function(callBack) {
     addCallback(callBack);
     requireAndInit();
},        

3、requireAndInit

     // 加载组件与页面进行初始化
    function requireAndInit() {
        //这个参数用于标记即将跳转问卷调查地址,无需再做后续的路由解析工作
        if (window.IS_QUESTIONNAIRE) {
            //更改状态,避免重复操作
            window.IS_QUESTIONNAIRE = false;
            return;
        }
        var require_page_path = []; //页面模块js路径
        var require_component_path = []; //公共组件js路径
        //设置公共组件路径和页面模块路径
        setJsPath(require_page_path, require_component_path);

        //需要选择角色
        var needSelectRole = window.IS_NEED_SELECTROLE == "1" && require_page_path[0] == "selectRoleIndex";
        //如果hash中有recallUrl参数,表示访问的是问卷调查,则不做角色选择
        if (window.location.hash.indexOf('recallUrl') != '-1' || window.location.search.indexOf('recallUrl') != '-1') {
            needSelectRole = false;
        }
        //不需要选择角色时,删除selectRole的dom
        if (!needSelectRole) {
            $('#selectrole').remove();
        }

        //加载公共组件
        require(require_component_path, function() {
            //注册公共组件
            window.REQUIRE_MODULES_ARR.defaultComponents.forEach(function(defaultComponent) {
                Vue.component(defaultComponent.name, spriteUtils.loadComponent(defaultComponent.jsPath));
            });
            var needSDK = true;
            //异步按需加载
            if (window.appLoadAsync) {
                init(needSDK, needSelectRole);
            }
            //全部加载
            else {
                require(require_page_path, function() {
                    init(needSDK, needSelectRole);
                });
            }
        });
    }

4、setJsPath:window.REQUIRE_MODULES_ARR中的页面路径在getAuthConfig中初始化完成

自定义的模块加载路径在pageRegister.xml中配置,通过getAuthConfig中/sys/swpubapp/MobileCommon/getMenuInfo.do从后台获取配置文件信息,解析成json格式返回给browser

     /**
     * 设置页面与组件的js文件路径
     */
    function setJsPath(require_page_path, require_component_path) {
        if (window.REQUIRE_MODULES_ARR.pageModules instanceof Array) {
            //页面模块js路径
            window.REQUIRE_MODULES_ARR.pageModules.forEach(function(pageModule) {
                require_page_path.push(pageModule.vueJsPath);
            });
        }
        if (window.REQUIRE_MODULES_ARR.defaultComponents instanceof Array) {
            //公共组件js路径
            window.REQUIRE_MODULES_ARR.defaultComponents.forEach(function(defaultComponent) {
                require_component_path.push(defaultComponent.jsPath);
            });
        }
    }

5、注册公共组件:Vue.component(defaultComponent.name, spriteUtils.loadComponent(defaultComponent.jsPath));

  • spriteUtils.loadComponent
  •          /**
             * 加载组件
             */
            loadComponent: function(path) {
                return function() {
                    var dfd = $.Deferred();
                    require([path], function(componentInit) {
                        var component = componentInit();
                        component.template = compileTpl(component.template);
                        dfd.resolve(component);
                    });
                    return dfd;
                };
            },
  • 使用require加载路径为path的自定义模块,每个自定义模块的格式如下,自定义模块返回一个匿名函数,
  • define(function(require, exports, module) {
        var tpl = require('text!publicVueComponent/selectrole/selectrole.html');
        var spriteUtils = require('spriteUtils');
        return 
              function() {
                var page = {
                    template: tpl,
                    data: function() {
                        return {
                        };
                    },
                    created: function() {
                       
                    },
                    updated: function() {
                    },
                    methods: {    
                   };
                return page;
        };
    
    });
  • 该匿名函数在app初始化时,通过require加载,得到函数componentInit,然后执行该函数,即执行return后面的function
  • 执行该函数,返回一个page对象,代表当前组件实例,此时数据并未进行初始化,仅得到了一个page对象,该page对象有vue的html模板template和一些列方法
  • var component = componentInit();
  •  component.template = compileTpl(component.template); 正则扫描模板文件,实现按钮权限,删除所有无权限的dom
  •     /**
         * 正则扫描模板文件,实现按钮权限
         */
        function compileTpl(tpl) {
            if (!window.MOBILE_BUTTONAUTH_LIST) {
                window.MOBILE_BUTTONAUTH_LIST = [];
            }
            //获取tpl中所有权限id
            var tplIds = [];
            var result;
            var pattern = new RegExp('auth-id=[\'|\"]{1}[^\'^\"]+[\'|\"]{1}', 'gm');
            while ((result = pattern.exec(tpl)) != null) {
                tplIds.push(result[0].substring(9, result[0].length - 1));
            };
            if (tplIds.length == 0) {
                return tpl;
            }
    
            //删除所有无权限的dom
            tplIds.forEach(function(id, index) {
                if (window.MOBILE_BUTTONAUTH_LIST.indexOf(id) < 0) {
                    var regExp = new RegExp('<[^/].*(auth.*?auth-id=[\'|\"]{1}' + id + '[\'|\"]{1}).*>[\\s\\S]*?</.*auth.*>', 'gm');
                    tpl = tpl.replace(regExp, "");
                }
            });
    
            return tpl;
        }

6、应用初始化

            //异步按需加载
            if (window.appLoadAsync) {
                init(needSDK, needSelectRole);
            }
            //全部加载
            else {
                require(require_page_path, function() {
                    init(needSDK, needSelectRole);
                });
            }
  •  function init(needSDK, needSelectRole) {}
  • 初始化路由

    if (needSelectRole) {
                rootDiv = '#selectrole';
                routes = [{
                    path: '/',
                    name: 'selectrole',
                    component: spriteUtils.loadComponent('selectRoleIndex')
                }];
            }
            //初始化当前用户有权限访问的页面
            else {
                routes = getVueRoute();
            }
    
            //生成VueRouter对象
            var router = new VueRouter({
                routes: routes
            });

     

  • 路由切换完成后执行的操作
  • router.afterEach(function(to, from, next) {
    	//页面离开时,关闭messagebox
    	mintUI.MessageBox.close();
    
    	/**
    	 * 当前端组件页面弹出遮罩层,为了控制遮罩层下的文本不滚动,
    	 * 在<body></body>与<div id="app"></div>上设置了样式:overflow:hidden;height:100%,锁死了页面。
    	 * 这边手动去除这个样式
    	 */
    	if (document.body.style.overflow == 'hidden' && document.body.style.height == '100%') {
    	    document.body.style.overflow = null;
    	    document.body.style.height = null;
    	    document.body.firstElementChild.style.overflow = null;
    	    document.body.firstElementChild.style.height = null;
    	}
    
    	/**
    	 * 在切换路由后自动执行一个轻微滑动
    	 * 这样写的原因:ios在页面的高度比较高时,从其他页面返回该页面将会出现页面空白的现象
    	 * 需要轻触屏幕进行滑动才能恢复原页面
    	 */
    	if (!to.meta.keepAlive && !from.meta.keepAlive) {
    	    var top = document.body.scrollTop;
    	    document.body.scrollTop = top + 1;
    	    setTimeout(function() {
    	        document.body.scrollTop = top - 1;
    	    }, 0);
    	}
    });
  • 路由切换操作1、切换为当前设置的自定义的router和router挂载的自定义div  2、切换为默认路由,挂载为默认的#app上
  • if (needSDK) {
        initSDKandApp(rootDiv, router);
    } else {
        //挂载主vue对象
        app = new Vue({
            el: '#app',
            router: router
        });
        finishedCallback()
    }
  • initSDKandApp初始化SDK与应用
  •  /**
     * 初始化SDK与应用
     */
    function initSDKandApp(rootDiv, router) {
    	if(/dingtalk/.test(navigator.userAgent.toLowerCase())){
    		getDDSign().then(function(signData) {
                var config = {                    
                    //钉钉jdk初始化参数
                    dd: {
                    	corp:signData.corpId,
                    	uploadImgsToEmapUrl: WIS_CONFIG.ROOT_PATH + '/sys/swpubapp/MobileCommon/saveFileFromDingding.do'
                    }
                };
                //如果获取到了微信签名,则用该签名对象初始化微信jssdk
                if ('{}' !== JSON.stringify(signData)) {
                    config.dd.signData = signData;
                }
    
                /**
                 * 判断父窗口中是否加载了SDK,如果加载了则直接使用父窗口的SDK
                 * 这样写的原因:微信SDK在同一页面初始化两次会造成第二次初始化失败
                 *               即使是iframe嵌套的页面也不行
                 */
                if (window.parent && window.parent.SDK) {
                    window.SDK = window.parent.SDK;
                    //挂载主vue对象
                    app = new Vue({
                        el: rootDiv,
                        router: router
                    });
                    finishedCallback();
                    return;
                }
    
                //使用BH_MOBILE提供的方法进行SDK的注册
                require(['BH_MOBILE'], function(BH_MOBILE) {
                    window.BH_MOBILE = BH_MOBILE;
                    //初始化sdk
                    BH_MOBILE.default(function(res) {
                        window.SDK = res.sdk;
                        //挂载主vue对象
                        app = new Vue({
                            el: rootDiv,
                            router: router
                        });
                        finishedCallback();
                    }, config);
                });
    
            });
    	}else{
    		getWechatSign().then(function(signData) {
                var config = {
                    //微信jdk初始化参数
                    wx: {
                        uploadImgsToEmapUrl: WIS_CONFIG.ROOT_PATH + '/sys/swpubapp/MobileCommon/saveFileFromWechat.do'
                    },
                    //钉钉jdk初始化参数
                    dd: {}
                };
                //如果获取到了微信签名,则用该签名对象初始化微信jssdk
                if ('{}' !== JSON.stringify(signData)) {
                    config.wx.signData = signData;
                }
    
                /**
                 * 判断父窗口中是否加载了SDK,如果加载了则直接使用父窗口的SDK
                 * 这样写的原因:微信SDK在同一页面初始化两次会造成第二次初始化失败
                 *               即使是iframe嵌套的页面也不行
                 */
                if (window.parent && window.parent.SDK) {
                    window.SDK = window.parent.SDK;
                    //挂载主vue对象
                    app = new Vue({
                        el: rootDiv,
                        router: router
                    });
                    finishedCallback();
                    return;
                }
    
                //使用BH_MOBILE提供的方法进行SDK的注册
                require(['BH_MOBILE'], function(BH_MOBILE) {
                    window.BH_MOBILE = BH_MOBILE;
                    //初始化sdk
                    BH_MOBILE.default(function(res) {
                        window.SDK = res.sdk;
                        //挂载主vue对象
                        app = new Vue({
                            el: rootDiv,
                            router: router
                        });
                        finishedCallback();
                    }, config);
                });
    
            });
    	}
        
    }

依据routes生成VueRouter对象:
        var router = new VueRouter({routes: routes });

router中有标识为index的页面,默认进入该页面,为展示的第一个页面,只有依据用户交互来切换页面和路由

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值