vue-router 版本 > v4.1.4 如何优雅传参?

vue-router v4.1.4 更新日志

官方似乎不再支持以下的写法了:

router.push({ name: 'somewhere', params: { oops: { a: { b: { c: 'gets removed'} } } })

这么写会提示: Discarded invalid param(s)...

官方推荐的替代方案:

  1. 将数据放入pinia等存储中
  2. path query
  3. HistoryState
  4. 将其作为新属性传递给to.meta 导航守卫

方案1感觉让代码变得过于复杂了。
方案2对于需要传递复杂的对象。而不是简单的字符串或数字的话似乎无法做到
方案4同1

方案3不太了解, 除了方案3, 请问有什么更优雅的写法吗?

阅读 1.5k
3 个回答

🙄 params 传递参数为什么不支持? 👉 编程式导航 | Vue Router
不支持的你没有在 router 配置的时候显式声明你的 params 参数啊!

const routes = [{ path: '/test/:oops', name: 'somewhere', component: somewhereComoponent }]

Vue2.x 时期,也就是 vue-router 3.x 版本的时候我们不想在URL上面展示一些传参信息的时候会通过不在路由配置中显式声明 params 参数,然后通过 router.push({ name: 'user', params: { username: 'eduardo' } }) 的方式去跳转。
这样就不会在URL中展示 params 参数。同时会在刷新页面时候丢失 params 参数,也起到一些特殊地业务处理方式。

但是在 vue-router 4.x 版本之后就不是这样了,如果没有显示声明 params 参数,在使用 router.push({ name: 'user', params: { username: 'eduardo' } }) 的方式去跳转地时候, vue-router 会把 params 参数给抛弃,并且在控制台抛出异常提示。

这其实是因为早期我们不规范的使用 params 造成的。如果你不想显式的在路由表中声明,那么也可以使用 query 参数的形式来替代。但是如果你想要传参的同时不要想在URL中显示参数信息,那么可以通过更新文档中提到的这些方式来操作。

我们使用对象作为参数 一般是不考虑参数丢失的情况的
可以自己封装一个NavTo, GetNavParams方法
如果想保留参数 可以存储到IndexedDB持久化

可以参考Zova的实现,不仅可以支持JSON对象,也支持Array数组,代码简洁、优雅:

1. 支持json对象

可以在 Query 中传递 json 对象。比如,我们在 Query 中定义一个 user 对象

export const QuerySchema = zz.object({
  user: zz
    .json({
      name: zz.string(),
      age: zz.number(),
    })
    .optional(),
});

在 render 中可以直接读取 user 对象的值

export class RenderCardHeader {
  render() {
    return (
      <div>
        <div>name: {this.$query.user?.name}</div>
        <div>age: {this.$query.user?.age}</div>
      </div>
    );
  }
}

2. 支持array数组

可以在 Query 中传递 array 数组。比如,我们在 Query 中定义一个 colors 数组

export const QuerySchema = zz.object({
  colors: zz.array(zz.string()).optional(),
});

在 render 中可以直接读取 colors 数组的值

export class RenderCardHeader {
  render() {
    return (
      <div>
        <div>colors: {this.$query.colors?.join(',')}</div>
        <div>length: {this.$query.colors?.length}</div>
      </div>
    );
  }
}
推荐问题
宣传栏