2023-07-04 Uniapp 路由跳转状态管理

  • 正在学习用Uniapp写小程序,仅作为学习的出口和记录

1. 创建router.js 封装Router对象

/* 
 * 路由对象
 * 中心思想:需要路由鉴权,由于uni-app没有vue中的全局钩子函数,所以封装了Router对象。
 * 说明:应用中的路由跳转尽量使用该Router的方法,并配合config中的路由表对象进行跳转。
 * 
 * 示例:this.$mRouter.push({route:this.$mRoutesConfig.main,query:{a:1}})
 * 
 */
class Router {
    constructor(arg) {
        
        this.callBack = () => {};
    }

    beforeEach(callBack) {
        if (callBack instanceof Function) this.callBack = callBack;
    }

    push(to) {
        this.callBack("navigateTo", to);
    }

    redirectTo(to) {
        this.callBack("redirectTo", to);
    }

    reLaunch(to) {
        this.callBack("reLaunch", to);
    }

    switchTab(to) {
        this.callBack("switchTab", to);
    }

    back(delta) {
        uni.navigateBack({
            delta
        })
    }
}

export default new Router();

2. 创建routes.config.js 封装路由表对象

/*
 * 路由表对象:
 * 该文件挂载在Vue原型中 $mRoutesConfig
 * 作用:调用$mRouter对象的方法 传入以下对应的路由对象,详细见common目录下的router.js
 * 示例:this.$mRouter.push({route:this.$mRoutesConfig.main,query:{a:1}})
 * 注意:所有在pages目录下新建的页面都必须在"路由表"中进行声明,并且在框架的pages.json注册。
 *
 * 配置参数项说明:
 * name:可选配置 (路由名称)
 * path:必填配置 (路由地址)
 * requiresAuth:可选配置 (是否权限路由)
 */

export default {
    // 权限路由 在main.js可实现路由拦截 所以路由都需要注册 待完善
    promoCode: {
        name: '创建订单',
        path: '/pages/order/create/order',
        requiresAuth: true
    },

    // 非权限路由
    main: {
        name: '首页',
        path: '/pages/index/index'
    },
    category: {
        name: '分类',
        path: '/pages/category/category'
    },
    cart: {
        name: '购物车',
        path: '/pages/cart/cart'
    },
    login: {
        name: '登录',
        path: '/pages/public/login'
    },
    index: {
        name: '注册',
        path: '/pages/public/register'
    },
    loginType: {
        name: '登录类型',
        path: '/pages/public/logintype'
    }
};

3.创建utils.js 对一些常用方法的封装

var innerAudioContext = uni.createInnerAudioContext();
export default {
    
    /**
     * 获取两个经纬度之间的距离
     * @param lat1 第一点的纬度
     * @param lng1 第一点的经度
     * @param lat2 第二点的纬度
     * @param lng2 第二点的经度
     * @returns {Number}
     */
    getDistance(lat11, lng11, lat22, lng22) {
        //格式转换,避免输入的string字符
        var lat1 = parseFloat(lat11);
        var lng1 = parseFloat(lng11);
        var lat2 = parseFloat(lat22);
        var lng2 = parseFloat(lng22);
        //相等的直接返回
        if(lat1==lat2 && lng1==lng2){
            return 0;
        }
        var f = this.getRad((lat1 + lat2) / 2);
        var g = this.getRad((lat1 - lat2) / 2);
        var l = this.getRad((lng1 - lng2) / 2);
        var sg = Math.sin(g);
        var sl = Math.sin(l);
        var sf = Math.sin(f);
        var s, c, w, r, d, h1, h2;
        var a = 6378137.0; //The Radius of eath in meter.   
        var fl = 1 / 298.257;
        sg = sg * sg;
        sl = sl * sl;
        sf = sf * sf;
        s = sg * (1 - sl) + (1 - sf) * sl;
        c = (1 - sg) * (1 - sl) + sf * sl;
        w = Math.atan(Math.sqrt(s / c));
        r = Math.sqrt(s * c) / w;
        d = 2 * w * a;
        h1 = (3 * r - 1) / 2 / c;
        h2 = (3 * r + 1) / 2 / s;
        s = d * (1 + fl * (h1 * sf * (1 - sg) - h2 * (1 - sf) * sg));
        s = s / 1000;
        s = s.toFixed(2); //指定小数点后的位数。   
        return s;
    },
    
    getRad(d) {
        var PI = Math.PI;
        return d * PI / 180.0;
    },
    
    /**
     * 当前位置与指定位置的距离
     * @param lat1 第一点的纬度
     * @param lng1 第一点的经度
     * @returns {Number}
     */
    getCurrentDistance(lat, lng) {
        let location=getApp().globalData.currentLocation;
        if (location) {
            return this.getDistance(lat, lng, location.latitude, location.longitude)
        }
        return 0;
    },
    
    /**
     * 当前位置与指定位置的距离
     * @param lat1 第一点的纬度
     * @param lng1 第一点的经度
     * @returns {Number}
     */
    getCurrentDistanceStr(lat, lng) {
        var distance = this.getCurrentDistance(lat, lng);
        var strDistance = '';
        if (distance < 1) { //一公里以内的
            strDistance = distance * 1000 +"m";
        } else {
            strDistance = distance+"km";
        }
        return strDistance;
    },
    
    
    phoneHiden(cellValue) {
        if (Number(cellValue) && String(cellValue).length === 11) {
            var mobile = String(cellValue)
            var reg = /^(\d{3})\d{4}(\d{4})$/
            return mobile.replace(reg, '$1****$2')
        } else {
            return cellValue
        }
    },

    playAudio(src) {
        if (innerAudioContext) {
            innerAudioContext.stop();
        }
        // 为了防止苹果手机静音无法播放
        wx.setInnerAudioOption({
            obeyMuteSwitch: false
        });
        innerAudioContext.src = encodeURI(src);
        console.log("开始播放");
        innerAudioContext.play();
        innerAudioContext.onEnded((res) => {
            console.log("自然播放结束")
            // callback("onEnded");
        });
        innerAudioContext.onStop((res) => {
            console.log("播放停止")
            // callback("onStop");
        });
        innerAudioContext.onError((res) => {
            console.log("播放错误", res)
            // callback("onError");
        })
    },

    stopAudioPlay() {
        console.log("stopAudioPlay", innerAudioContext);
        if (innerAudioContext) {
            console.log("stopAudioPlay");
            innerAudioContext.stop();
        }
    },


    /* 
     * 将cityNo 转 cityName
     * cityData:原数据
     * cityNo:二级地区编码
     */
    getCityName(cityData, cityNo) {
        if (!cityNo) return;
        if (!(cityData instanceof Array)) return;
        // 9112
        cityNo += "";
        for (let i = 0; i < cityData.length; i++) {
            let sheng = cityData[i];
            for (let j = 0; j < sheng.children.length; j++) {
                let shi = sheng.children[j];
                if (shi.value == cityNo) {
                    // 使用return 终止循环
                    return `${sheng.label}-${shi.label}`;
                }
            }
        }
    },

    /* 
     * obj 转 params字符串参数  
     * 例子:{a:1,b:2} => a=1&b=2
     */
    objParseParam(obj) {
        let paramsStr = "";
        if (obj instanceof Array) return paramsStr;
        if (!(obj instanceof Object)) return paramsStr;
        for (let key in obj) {
            paramsStr += `${key}=${obj[key]}&`;
        }
        return paramsStr.substring(0, paramsStr.length - 1);
    },

    /* 
     * obj 转 路由地址带参数
     * 例子:{a:1,b:2} => /pages/index/index?a=1&b=2
     */
    objParseUrlAndParam(path, obj) {
        let url = path || "/";
        let paramsStr = "";
        if (obj instanceof Array) return url;
        if (!(obj instanceof Object)) return url;
        paramsStr = this.objParseParam(obj);
        paramsStr && (url += "?");
        url += paramsStr;
        return url;
    },

    /* 
     * 获取url字符串参数
     */
    getRequestParameters(locationhref) {
        let href = locationhref || "";
        let theRequest = new Object();
        let str = href.split("?")[1];
        if (str != undefined) {
            let strs = str.split("&");
            for (let i = 0; i < strs.length; i++) {
                theRequest[strs[i].split("=")[0]] = (strs[i].split("=")[1]);
            }
        }
        return theRequest;
    },

    /* 
     * 银行卡每四位空格
     */
    formatCardNo(cardNo) {
        cardNo += "";
        return cardNo.replace(/\s/g, '').replace(/[^\d]/g, '').replace(/(\d{4})(?=\d)/g, '$1 ');
    },

    /**
     * 乘法,解决js精度损失问题
     * @param {*} arg1 
     * @param {*} arg2 
     */
    accMul(arg1, arg2) {
        arg1 = arg1 || 0;
        var m = 0,
            s1 = arg1.toString(),
            s2 = arg2.toString();
        try {
            m += s1.split(".")[1].length
        } catch (e) {}
        try {
            m += s2.split(".")[1].length
        } catch (e) {}
        return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m)
    },
}

4.main.js引入+挂载

// 引入全局配置
import $mRoutesConfig from '@/config/routes.config.js';
// 引入全局方法
import $mRouter from '@/common/router.js';
import $mUtils from "@/common/utils.js"
// 挂载全局自定义方法
Vue.prototype.$mRoutesConfig = $mRoutesConfig;

Vue.prototype.$mUtils = $mUtils;
Vue.prototype.$mRouter = $mRouter;

5.main.js 路由守卫

$mRouter.beforeEach((navType, to) => {
    if (to.route === undefined) {
        throw '路由钩子函数中没有找到to对象,路由信息:' + JSON.stringify(to);
    }
    if (to.route === $mRoutesConfig.login.path && store.getters.hasLogin) {
        uni.reLaunch({
            url: $mHelper.objParseUrlAndParam($mRoutesConfig.main.path)
        });
        return;
    }
    // 过滤需要权限的页面
    if (to.route.requiresAuth) {
        if (store.getters.hasLogin) {
            // 已经登录
            uni[navType]({
                url: $mHelper.objParseUrlAndParam(to.route.path, to.query)
            });
        } else {
            // 登录成功后的重定向地址和参数
            const query = {
                redirectUrl: to.route.path,
                ...to.query
            };
        }
    } else {
        uni[navType]({
            url: $mHelper.objParseUrlAndParam(to.route, to.query)
        });
    }
});
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容