Blame view

node_modules/uview-ui/libs/util/route.js 3.77 KB
c7add6cf   “wangming”   初始版本开发完毕
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
  /**

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