如何使用Vue-Router在Vue中设置URL查询参数

Sau*_*abh 81 javascript vue.js vue-router

我正在尝试在更改输入字段时使用Vue-router设置查询参数,我不想导航到其他页面但只想在同一页面上修改url查询参数,我这样做:

this.$router.replace({ query: { q1: "q1" } })
Run Code Online (Sandbox Code Playgroud)

但这也会刷新页面并将y位置设置为0,即滚动到页面顶部.这是设置URL查询参数的正确方法,还是有更好的方法.


编辑:

这是我的路由器代码:

export default new Router({
  mode: 'history',
  scrollBehavior: (to, from, savedPosition)  => {
    if (to.hash) {
      return {selector: to.hash}
    } else {
      return {x: 0, y: 0}
    }
  },
  routes: [
    ....... 
    { path: '/user/:id', component: UserView },
  ]
})
Run Code Online (Sandbox Code Playgroud)

Man*_*ani 91

以下是docs中的示例:

// with query, resulting in /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})
Run Code Online (Sandbox Code Playgroud)

参考:https://router.vuejs.org/en/essentials/navigation.html

正如那些文档中所提到的router.replace那样router.push

所以,您似乎在您的示例代码中正确使用它.但我认为您可能还需要包含namepath参数,以便路由器有一些导航路由.没有一个namepath它,它看起来不是很有意义.

这是我现在的理解:

  • query 对于路由器是可选的 - 组件构建视图的一些附加信息
  • name或者path是强制性的 - 它决定在您的组件中显示哪个组件<router-view>.

这可能是示例代码中缺少的东西.

编辑:评论后的其他详细信息

在这种情况下你尝试过使用命名路由吗?您有动态路由,并且更容易单独提供参数和查询:

routes: [
    { name: 'user-view', path: '/user/:id', component: UserView },
    // other routes
]
Run Code Online (Sandbox Code Playgroud)

然后在你的方法中:

this.$router.replace({ name: "user-view", params: {id:"123"}, query: {q1: "q1"} })
Run Code Online (Sandbox Code Playgroud)

从技术上讲,上述和之间没有区别this.$router.replace({path: "/user/123", query:{q1: "q1"}}),但是在命名路径上提供动态参数比组成路径字符串更容易.但在任何一种情况下,都应该考虑查询参数.在任何一种情况下,我都没有发现查询参数的处理方式有任何问题.

在你进入路线后,你可以获取动态参数this.$route.params.id,你的查询参数为this.$route.query.q1.


Chi*_*LiO 29

好吧,我一直在尝试向我现有的网址添加一个参数,该网址已经有一周了,哈哈,原始网址:http://localhost:3000/somelink?param1=test1 我一直在尝试:

this.$router.push({path: this.$route.path, query: {param2: test2} });
Run Code Online (Sandbox Code Playgroud)

这段代码只会删除 param1 并变成 http://localhost:3000/somelink?param2=test2

为了解决这个问题我使用了fullPath

this.$router.push({path: this.$route.fullPath, query: {param2: test2} });
Run Code Online (Sandbox Code Playgroud)

现在我成功地在旧参数上添加了参数,结果是

http://localhost:3000/somelink?param1=test1&param2=test2


And*_*e M 13

如果你试图保留一些参数,同时改变其他参数,请确保复制 vue 路由器查询的状态,而不是重复使用它。

这是有效的,因为您正在制作未引用的副本:

  const query = Object.assign({}, this.$route.query);
  query.page = page;
  query.limit = rowsPerPage;
  await this.$router.push({ query });
Run Code Online (Sandbox Code Playgroud)

而下面将导致 Vue Router 认为您正在重用相同的查询并导致NavigationDuplicated错误:

  const query = this.$route.query;
  query.page = page;
  query.limit = rowsPerPage;
  await this.$router.push({ query });
Run Code Online (Sandbox Code Playgroud)

当然,您可以分解查询对象,如下所示,但您需要了解页面的所有查询参数,否则您可能会在结果导航中丢失它们。

  const { page, limit, ...otherParams } = this.$route.query;
  await this.$router.push(Object.assign({
    page: page,
    limit: rowsPerPage
  }, otherParams));
);
Run Code Online (Sandbox Code Playgroud)

请注意,虽然上面的示例适用于push(),但这也适用replace()

使用 vue-router 3.1.6 测试。


jea*_*rme 11

实际上你可以像这样推送查询: this.$router.push({query: {plan: 'private'}})

基于:https://github.com/vuejs/vue-router/issues/1631

  • “但是这也会刷新页面” (4认同)
  • 这里对“刷新页面”的含义存在误解。硬刷新(如 F5)和实际的 vue-router 客户端导航是两个不同的东西。在这里,jean 的解决方案不会触发“页面硬刷新”,同时它会触发 vue-router 导航和可能的挂载/卸载特定组件。OP确实不想要的东西。 (2认同)

hay*_*ran 9

我的解决方案,不刷新页面,也没有错误Avoided redundant navigation to current location

    this.$router.replace(
      {
        query: Object.assign({ ...this.$route.query }, { newParam: 'value' }),
      },
      () => {}
    )
Run Code Online (Sandbox Code Playgroud)


Goo*_*Mac 7

这是我在不刷新页面的情况下更新 URL 中的查询参数的简单解决方案。确保它适用于您的用例。

const query = { ...this.$route.query, someParam: 'some-value' };
this.$router.replace({ query });
Run Code Online (Sandbox Code Playgroud)


Lud*_*fyn 7

您也可以只使用浏览器window.history.replaceStateAPI。它不会重新安装任何组件,也不会导致冗余导航。

window.history.replaceState(null, '', '?query=myquery');
Run Code Online (Sandbox Code Playgroud)

更多信息请点击这里。


Bos*_*nne 6

this.$router.push({ query: Object.assign(this.$route.query, { new: 'param' }) })
Run Code Online (Sandbox Code Playgroud)

  • 我最喜欢这个答案。不幸的是,这会导致“错误:避免了到当前位置的冗余导航” (2认同)
  • 但现在我想你可以这样做`this.$router.push({ query: {...this.$route.query,new: 'param'},) })` (2认同)

Man*_*piK 5

无需重新加载页面或刷新dom,history.pushState就可以完成工作。
在您的组件或其他地方添加此方法可以做到这一点:

addParamsToLocation(params) {
  history.pushState(
    {},
    null,
    this.$route.path +
      '?' +
      Object.keys(params)
        .map(key => {
          return (
            encodeURIComponent(key) + '=' + encodeURIComponent(params[key])
          )
        })
        .join('&')
  )
}
Run Code Online (Sandbox Code Playgroud)

因此,在组件中的任何位置调用addParamsToLocation({foo: 'bar'}),以使用window.history堆栈中的查询参数推送当前位置。

要将查询参数添加到当前位置而无需推送新的历史记录条目,请history.replaceState改用。

使用Vue 2.6.10和Nuxt 2.8.1进行了测试。

 

使用这种方法要小心!
Vue Router不知道url已更改,因此在pushState之后它不会反映url。


小智 5

为了添加多个查询参数,这对我有用(从这里https://forum.vuejs.org/t/vue-router-programmatically-append-to-querystring/3655/5)。

\n\n
\n

上面的答案很接近\xe2\x80\xa6,尽管使用Object.assign它会改变this.$route.query,这不是你想要做的\xe2\x80\xa6确保在执行Object时第一个参数是{} 。分配

\n
\n\n
this.$router.push({ query: Object.assign({}, this.$route.query, { newKey: \'newValue\' }) });\n
Run Code Online (Sandbox Code Playgroud)\n