/**  
 | 
 * 路由跳转方法,该方法相对于直接使用uni.xxx的好处是使用更加简单快捷  
 | 
 * 并且带有路由拦截功能  
 | 
 */  
 | 
  
 | 
class Router {  
 | 
    constructor() {  
 | 
        // 原始属性定义  
 | 
        this.config = {  
 | 
            type: 'navigateTo',  
 | 
            url: '',  
 | 
            delta: 1, // navigateBack页面后退时,回退的层数  
 | 
            params: {}, // 传递的参数  
 | 
            animationType: 'pop-in', // 窗口动画,只在APP有效  
 | 
            animationDuration: 300, // 窗口动画持续时间,单位毫秒,只在APP有效  
 | 
            intercept: false // 是否需要拦截  
 | 
        }  
 | 
        // 因为route方法是需要对外赋值给另外的对象使用,同时route内部有使用this,会导致route失去上下文  
 | 
        // 这里在构造函数中进行this绑定  
 | 
        this.route = this.route.bind(this)  
 | 
    }  
 | 
  
 | 
    // 判断url前面是否有"/",如果没有则加上,否则无法跳转  
 | 
    addRootPath(url) {  
 | 
        return url[0] === '/' ? url : `/${url}`  
 | 
    }  
 | 
  
 | 
    // 整合路由参数  
 | 
    mixinParam(url, params) {  
 | 
        url = url && this.addRootPath(url)  
 | 
  
 | 
        // 使用正则匹配,主要依据是判断是否有"/","?","="等,如“/page/index/index?name=mary"  
 | 
        // 如果有url中有get参数,转换后无需带上"?"  
 | 
        let query = ''  
 | 
        if (/.*\/.*\?.*=.*/.test(url)) {  
 | 
            // object对象转为get类型的参数  
 | 
            query = uni.$u.queryParams(params, false)  
 | 
            // 因为已有get参数,所以后面拼接的参数需要带上"&"隔开  
 | 
            return url += `&${query}`  
 | 
        }  
 | 
        // 直接拼接参数,因为此处url中没有后面的query参数,也就没有"?/&"之类的符号  
 | 
        query = uni.$u.queryParams(params)  
 | 
        return url += query  
 | 
    }  
 | 
  
 | 
    // 对外的方法名称  
 | 
    async route(options = {}, params = {}) {  
 | 
        // 合并用户的配置和内部的默认配置  
 | 
        let mergeConfig = {}  
 | 
  
 | 
        if (typeof options === 'string') {  
 | 
            // 如果options为字符串,则为route(url, params)的形式  
 | 
            mergeConfig.url = this.mixinParam(options, params)  
 | 
            mergeConfig.type = 'navigateTo'  
 | 
        } else {  
 | 
            mergeConfig = uni.$u.deepMerge(this.config, options)  
 | 
            // 否则正常使用mergeConfig中的url和params进行拼接  
 | 
            mergeConfig.url = this.mixinParam(options.url, options.params)  
 | 
        }  
 | 
  
 | 
        // 如果本次跳转的路径和本页面路径一致,不执行跳转,防止用户快速点击跳转按钮,造成多次跳转同一个页面的问题  
 | 
        if (mergeConfig.url === uni.$u.page()) return  
 | 
  
 | 
        if (params.intercept) {  
 | 
            this.config.intercept = params.intercept  
 | 
        }  
 | 
        // params参数也带给拦截器  
 | 
        mergeConfig.params = params  
 | 
        // 合并内外部参数  
 | 
        mergeConfig = uni.$u.deepMerge(this.config, mergeConfig)  
 | 
        // 判断用户是否定义了拦截器  
 | 
        if (typeof uni.$u.routeIntercept === 'function') {  
 | 
            // 定一个promise,根据用户执行resolve(true)或者resolve(false)来决定是否进行路由跳转  
 | 
            const isNext = await new Promise((resolve, reject) => {  
 | 
                uni.$u.routeIntercept(mergeConfig, resolve)  
 | 
            })  
 | 
            // 如果isNext为true,则执行路由跳转  
 | 
            isNext && this.openPage(mergeConfig)  
 | 
        } else {  
 | 
            this.openPage(mergeConfig)  
 | 
        }  
 | 
    }  
 | 
  
 | 
    // 执行路由跳转  
 | 
    openPage(config) {  
 | 
        // 解构参数  
 | 
        const {  
 | 
            url,  
 | 
            type,  
 | 
            delta,  
 | 
            animationType,  
 | 
            animationDuration  
 | 
        } = config  
 | 
        if (config.type == 'navigateTo' || config.type == 'to') {  
 | 
            uni.navigateTo({  
 | 
                url,  
 | 
                animationType,  
 | 
                animationDuration  
 | 
            })  
 | 
        }  
 | 
        if (config.type == 'redirectTo' || config.type == 'redirect') {  
 | 
            uni.redirectTo({  
 | 
                url  
 | 
            })  
 | 
        }  
 | 
        if (config.type == 'switchTab' || config.type == 'tab') {  
 | 
            uni.switchTab({  
 | 
                url  
 | 
            })  
 | 
        }  
 | 
        if (config.type == 'reLaunch' || config.type == 'launch') {  
 | 
            uni.reLaunch({  
 | 
                url  
 | 
            })  
 | 
        }  
 | 
        if (config.type == 'navigateBack' || config.type == 'back') {  
 | 
            uni.navigateBack({  
 | 
                delta  
 | 
            })  
 | 
        }  
 | 
    }  
 | 
}  
 | 
  
 | 
export default (new Router()).route 
 |