Taro 封装路由系统

  • 我们在开发一个项目的时候,对于路由系统一般都会在原来的基础上进行二次封装。以此达到路由拦截、定制化功能、ts 类型限制 等等相关功能的目的。这篇文章分享一下在项目中路由封装的奇淫技巧。

Taro 信息

1、版本:taro3.x
2、应用端:小程序
3、技术栈:React hooks

定义一个跳转路由的方式

  • $.router 是在 app.tsx 里面全局注入的,注入后,在所有文件里面都可以调用
  • push 是一个跳转的方法,也可以叫其他名字
  • 参数1 是跳转的路径,参数2 是带给下一个页面的参数
$.router.push('/pages/index/index', { 
	name: 'ajin',
	age: 30,
	isMarry: false,
	hobbys: {
		sports: ['run']
	},
	other: undefined,
})

push 方法的代码


class Router {
	push = (url, params) => {
		// 处理 params,下一步会介绍这个函数的作用
		const newParams = formatRouterParams(params)
		// navigateToBefore()
		Taro.navigateTo(url, newParams)
	}
}
  • 我们知道参数传给下一个页面的时候,是以字符串的形式传过去的?name=ajin&age=30 …
  • 很多情况下,我们传过去一个数字或者boolean,接受到的也是一个字符串。例如:isMarry: “false”,
  • 这样有两个问题
  • 1、不利于类型约束;2、判断boolean 和 undefined 不方便
  • 我们这样来,在传入的每个类型前面加一个前缀。然后到解析路由参数的时候就根据前缀的类型解析成 对应的 类型。
    1、number 类型 #num#111
    2、boolean 类型 #bool#true
    3、object 类型 #obj#{a: 1}
    4、undefined 类型 #und#undefined
const formatRouterParams = (params?: Record<string, any>) => {
  if(!params) return params
  let newPrams = {}
  Object.entries(params).forEach(([key, value]) => {
    const keyType = typeof value
    switch(keyType) {
      case 'number' :
        newPrams[key] = `#num#${value}`
        break;
      case 'boolean' :
        newPrams[key] = `#bool#${value}`
        break;
      case 'object' : 
        newPrams[key] = `#obj#${JSON.stringify(value)}`
        break;
      case 'undefined' : 
        newPrams[key] = `#und#${value}`
        break;
      default :
      newPrams[key] = value
    }
  })
  return newPrams
}
  • 格式化后的参数就是这样,前面都带了当前的类型
    在这里插入图片描述

编写解析路由的 hook

  • taro useRouter 会自动解析 你路径上的路由,并且以键值对的形式输出。如上图打印的数据格式一致
import {  useRouter } from "@tarojs/taro"

/** 
 * @description 获取 格式化后的 路由参数
 */
const useRouterParams = () => {
  const { params } = useRouter()
  let newPrams = {} 

  Object.entries(params).forEach(([key, value]) => {
     // taro 自带的参数
     if(key === '$taroTimestamp') return

     if(!value) return newPrams[key] = value
     // 数字类型
     if(value.startsWith("#num#")) {
       newPrams[key] = parseFloat(value.replace('#num#', ''))
 
     // boolean 类型
     } else if(value.startsWith("#bool#")) {
       newPrams[key] = value.replace('#bool#', '') === "true"
     
     // 对象类型 
     } else if(value.startsWith("#obj#")) {
       newPrams[key] = JSON.parse(value.replace('#obj#', ''))
     
     // undefined 类型
     } else if (value.startsWith('#und#')) {
       newPrams[key] = undefined
     }else {
       newPrams[key] = value
     }
  })
  return newPrams 
}

export default useRouterParams
  • 这个hook 跟据 前面定制的规则,把参数解析成对应的类型。解析出来和我们传入进去的对象是一致的。
    在这里插入图片描述

参数问题解决了,接下来我们来解决ts 问题。

  • taro-export-route-type 这个插件,会根据你app.config.ts 的路由配置生成一个路由 的 联合类型。根据配置可以生成对应路径的文件

在这里插入图片描述

  • 声明每个页面,到下一个页面需要传递 参数的类型
export type PageParams = {
  /** 首页 */
  '/pages/index/index': {
    /** 名字 */
    name: string,
	age: number,
	isMarry: boolean,
	hobbys: Record<string, any>
	other?: string,
  },
}
  • push 函数的类型声明
export type Push = <T extends Pages>(url: T, params?: PageParams[T]) => viod 
  • 这样在选择跳转页面的时候就会有页面提示
    在这里插入图片描述
  • 后面的参数也有对应的类型
    在这里插入图片描述
  • useRouterParams 的 ts 类型
const useRouterParams = <T>(): T extends Params ? PageParams[T] : unknown => {}
  • 泛型传入后,对应的类型就出来了
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值