125 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			125 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 
								 | 
							
								/**
							 | 
						|||
| 
								 | 
							
								 * 路由跳转方法,该方法相对于直接使用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
							 |