jiangping
2023-10-26 68c5ef7d9fea3f911e250fb5f8b300bc76099e49
minipro_standard/uni_modules/uview-ui/libs/util/route.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,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