用了都说好的 uniapp 路由框架

背景

在使用 uni-app 开发项目时,路由跳转是极为频繁的操作,uni-app 提供的路由跳转 api uni.navigateTo够用但是却不够好用,主要问题在于,实际业务中经常涉及大量对象传参的情况,而 uni-app 只支持 query 参数,这就导致,对于对象的传参,必须通过encodeURIComponent先编码,然后在新的页面再通过decodeURIComponent进行解码,为了编码 url,还要拼接&,导致一个页面跳转传参又臭又长,可读性还很差,比如像下面这样:

js 复制代码
uni.navigateTo({
    url: '/pages/test/pay?question_id=' +
    res.data.id + '&service=' +
    encodeURIComponent(JSON.stringify(
        service)) + '&doctor=' +
    encodeURIComponent(
        JSON.stringify({
            name: this.doctor.name,
    dept_name: this.doctor
    .dept_name,
    dept_code: this.doctor
    .dept_code,
    code: this.doctor.code
    })) + '&description=' +
    encodeURIComponent(desc)
})

光看着就头大,要增加一个传参或者修改一个传参,都很考察眼力,寻找拼接的位置,获取参数的时候,也很鸡肋:

js 复制代码
onLoad: function(query) {
  this.pageHeight = uni.getSystemInfoSync().windowHeight
  this.question_id = query.question_id
  this.service = JSON.parse(decodeURIComponent(query.service.replace(/%/g, '%25')))
  this.doctor = JSON.parse(decodeURIComponent(query.doctor.replace(/%/g, '%25')))
  this.description = decodeURIComponent(query.description.replace(/%/g, '%25'))
}

由此,解决这一痛点就势在必行了,项目中虽然使用了u-view框架,提供了$u.route的方法,对 uni-app 的路由跳转方法进行简单的封装,可以支持通过第二个参数以对象的方式传参:

js 复制代码
this.$u.route({
  url: 'pages/components/empty/index',
  params: {
    name: 'lisa'
  }
})

其优点是,对路由跳转传参友好了一点,看起来更简洁些,但是也仅此而已了,存在的缺陷也很大,主要在于:

  • 仅支持值类型的传参,不支持引用类型传参,仍旧未解决实际业务中对对象数据传参的需要。
  • 阉割版的封装,无法传递events,对实际业务中页面返回的回调无法监听。

u-view也启发了我对路由封装的一些思路,结合对axios的使用,我对uni-app的路由跳转方法进行了定制化的封装,并单独发布了包caring-route,且成功在业务中使用,基本解决了上述问题。

caring-route 的特点

  • 继承了uni-app 的所有路由跳转方法,更加方便调用,名称更简洁
  • 支持跳转 tabBar 页面
  • 支持 events
  • 支持成功失败回调
  • 支持传递引用类型路由参数
  • 支持解析路由参数
  • rollup打包压缩,体积更小,仅有2.7kb
  • 支持跳转小程序

支持两种调用方法

  1. 函数调用:route(url[,config])
  2. 类的实例方法调用:route[method](url[,params])
  • method 的类型:
    • to
    • back
    • tab
    • redirect
    • launch
    • mini 跳转小程序
    • query 解析路由参数

快速上手

安装

bash 复制代码
npm i caring-route

使用

vue

html 复制代码
<script>
  import route from 'caring-route'

  route('/pages/index/home')
</script>

基础使用

对于不需要传递参数的路由跳转,route函数提供了原生的方法名称和简化的方法名称,并支持两种传参方式:

一种是类似u-view的,传递两个参数route(url,data),第一个参数url就是要跳转的路由,第二个参数data则是要传递的参数,与$u.route的区别就是支持传递对象参数,是其加强版,当只需要跳转路由和传递参数时,推荐优先使用route(url,data)的调用方式。

第二种是类uni-app的调用方法,传递一个参数route(config),其基本使用和 uni-app 是相同的,区别在于:

  • uniapp中参数需要通过query参数拼到 url 上,而route(config)url只传递跳转的页面路径即可,其页面参数用data或者params来接收。
  • uniapp中需要通过不同的方法navigateToredirectTo等来执行不同的路由跳转,而route(config)支持type参数来指定跳转类型是navigateTo还是redirectTo

下面具体说明

传递两个参数route(url,data)的使用方法

对于uni.navigateTo的封装

这个方法是路由跳转中最常使用的 api,caring-route做了三种方法的封装,三个方法是等价的,实际业务中,直接使用route()函数是最方便的

js 复制代码
// uni.navigateTo
route('/pages/index/home')
route.to('/pages/index/home')
route.navigateTo('/pages/index/home')

对于uni.redirectTo的封装

js 复制代码
// redirectTo
route.direct('/pages/index/home')
route.redirectTo('/pages/index/home')

对于uni.reLaunch的封装

js 复制代码
route.launch('/pages/index/home')
route.reLaunch('/pages/index/home')

对于uni.navigateBake的封装

js 复制代码
// back
route.back(delta)
route.navigateBake(delta)

对于uni.switchTab的封装

js 复制代码
// switchTab
route.tab('pages/index/index')
route.switchTab('pages/index/index')

传递路由跳转参数

route函数传入第二个参数,类型为对象,即为传递的路由参数,

js 复制代码
route('/pages/index/home', {
  name: 'wanko',
  age: '25',
  hoby: {
    guitar: {
      level: 1
    }
  }
})
route.to('/pages/index/home', {
  name: 'wanko',
  age: 25,
  hoby: {
    guitar: {
      level: 1
    }
  }
})

route.launch('pages/index/index', {
  msg: 'relunch过来'
})
route.redirect('/pages/index/home', {
  msg: 'redirect过来'
})

传递一个参数route(config)的使用方法

js 复制代码
route({
    url:'/pages/index/home',
    type: 'navigateTo',// 默认的跳转方式,可不传
    data: {
      name: 'wanko',
        age: 25,
        hoby: {
          guitar: {
            level: 1
          }
        },
        arr: [1, 2, 3, 4, 5],
        arrObj: [
          {
            name: 'wanko'
          },
          23,
          'age'
        ]
    },
    events: {
      onSuccess: (data) => {
        console.log('onSuccess', data)
      }
    }
  })

监听events事件

js 复制代码
// A页面
route({
  type: 'navigateTo', // 如果是navigateTo,可以不传type
  url: '/pages/index/home', 
  events: {
    onSuccess: (data) => {
      console.log('onSuccess', data)
    }
  },
})

// B页面
const eventChannel = this.getOpenerEventChannel();
eventChannel.emit('onSuccess', {
  data: 'data from home'
})
route.back()

获取路由参数

在onLoad中使用route的 query 方法传入 options ,函授调用的返回值为已经解码的路由参数

js 复制代码
onLoad(options) {
  const query = route.query(options)
}

处理跳转成功的回调

使用函数调用方式,添加 .then

js 复制代码
route('pages/index/index').then(res => console.log('跳转成功'))

跳转微信小程序

使用 mini(appId, path) 方法来跳转微信小程序

js 复制代码
route.mini('wx-appid', 'pages/tabbar/components').then(() => {
  console.log('跳转成功')
})
相关推荐
冴羽3 小时前
2026 年 Web 前端开发的 8 个趋势!
前端·javascript·vue.js
码银4 小时前
ruoyi的前端(vue)新增的时候给字典设置默认值 但不能正常
前端
凌览4 小时前
别再死磕 Nginx!http-proxy-middleware 低配置起飞
前端·后端
EndingCoder5 小时前
类的继承和多态
linux·运维·前端·javascript·ubuntu·typescript
用户47949283569155 小时前
React 终于出手了:彻底终结 useEffect 的"闭包陷阱"
前端·javascript·react.js
程序员猫哥5 小时前
前端开发,一句话生成网站
前端
Younglina5 小时前
一个纯前端的网站集合管理工具
前端·vue.js·chrome
木头程序员5 小时前
前端(包含HTML/JavaScript/DOM/BOM/jQuery)基础-暴力复习篇
开发语言·前端·javascript·ecmascript·es6·jquery·html5
卖火箭的小男孩5 小时前
# Flutter Provider 状态管理完全指南
前端