All files / mp navigatePageTo.ts

82.14% Statements 23/28
75% Branches 15/20
90% Functions 9/10
82.14% Lines 23/28

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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                                            6x 6x     6x     6x 6x 6x 1x 1x 1x     6x 2x 2x 2x     6x 1x 1x           6x 6x 6x                 6x     6x     6x 6x                      
import { AnyObject } from '../types'
import { createUrlQueryString, isUrl } from '../utils'
import { ensureInMiniProgram } from './ensureInMiniProgram'
import { getMiniProgramConfig } from './miniProgramConfig'
import { miniProgramBus } from './miniProgramBus'
 
/**
 * 跳转至某个页面,跳转失败时会尝试切换到 Tab 页。
 *
 * **注意:在页面真正切换后 Promise 才会被 resolve,因而此时的页面上下文已经是新页面。**
 *
 * @param url 要跳转去的页面地址
 * @param query 查询参数
 * @param redirect 是否关闭当前页面后跳转
 */
export function navigatePageTo(
  url: string,
  query?: AnyObject,
  redirect?: boolean,
): Promise<any> {
  let routeChanged: boolean
  let routeChangeResolve: AnyFunction
  const offRouteChange = miniProgramBus.once('routeChange', () => {
    Iif (routeChangeResolve) {
      routeChangeResolve()
    } else {
      routeChanged = true
    }
  })
  return new Promise<void>((resolve, reject) => {
    ensureInMiniProgram(mp => {
      if (isUrl(url)) {
        const { webUrlToMiniProgramUrl } = getMiniProgramConfig()
        if (typeof webUrlToMiniProgramUrl === 'function') {
          url = webUrlToMiniProgramUrl(url)
        }
      }
      if (query && typeof query === 'object') {
        const queryString = createUrlQueryString(query)
        if (queryString) {
          url += (url.indexOf('?') > -1 ? '&' : '?') + queryString
        }
      }
      const switchTab = () =>
        new Promise((resolve, reject) => {
          mp.switchTab({
            url: url,
            success: resolve,
            fail: reject,
          })
        })
      const navigateTo = () =>
        new Promise((resolve, reject) => {
          ;(redirect
            ? ((mp.redirectTo as any) as typeof mp.navigateTo)
            : mp.navigateTo)({
            url: url,
            success: resolve,
            fail: reject,
          })
        })
      // 支付宝下 navigateTo、redirectTo 也能跳转到 Tab 页并不会报错,只是不会显示 Tab 栏
      Iif (mp.$brand === '支付宝') {
        return switchTab().catch(navigateTo)
      }
      return navigateTo().catch(switchTab)
    })
      .then(() => {
        if (routeChanged) {
          resolve()
        } else E{
          routeChangeResolve = resolve
        }
      })
      .catch(() => {
        offRouteChange()
        reject()
      })
  })
}