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


114

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

this.$router.replace({ query: { q1: "q1" } })

但这也会刷新页面并将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 },
  ]
})

Answers:


132

这是docs中的示例:

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

参考: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
]

然后在您的方法中:

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

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

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


我也尝试提供路径,但这并没有停止滚动到页面顶部,我也使用路由器选项编辑了问题,可能在那里需要进行一些更改。
萨拉巴

您的查询参数是否打算滚动到文档中的正确位置?像您对锚标签提出的其他问题一样?
玛尼

不,我只想在URL中添加查询参数,我不想在这里滚动。
萨拉巴

我只是在本地设置中测试了选项,查询参数正常工作。我能够导航到新路线并访问查询参数,如更新后的答案所示。因此,问题是-您不希望它滚动吗?还是问题是整个应用程序再次刷新?
玛尼

因此,我在同一页面上,当我选择一些输入时,我想将它们添加到URL中,但是当我输入时,会发生滚动。滚动是我的问题。我不是要导航到其他页面,我只是想在同一页面上,似乎添加/修改url查询参数。
萨拉巴

15

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

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

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

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

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

请谨慎使用此方法!
Vue Router不知道url已更改,因此在pushState之后它不会反映url。



4
this.$router.push({ query: Object.assign(this.$route.query, { new: 'param' }) })

1
我最喜欢这个答案。不幸的是,这导致Error: Avoided redundant navigation to current location
Max Coplan

修复:this.$router.push({ query: Object.assign({...this.$route.query}, { new: 'param' }) })
Max Coplan

2
但是,现在我考虑到您可以做的this.$router.push({ query: {...this.$route.query,new: 'param'},) })
Max Coplan

3

如果尝试保留某些参数,而更改其他参数,请确保复制vue路由器查询的状态,并且不要重复使用。

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

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

而以下内容会导致Vue Router认为您正在重用同一查询并导致NavigationDuplicated错误:

  const query = this.$route.query;
  query.page = page;
  query.limit = rowsPerPage;
  await this.$router.push({ query });

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

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

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

已通过vue-router 3.1.6测试。



2

要一次设置/删除多个查询参数,我将以下方法作为全局混合(this作为vue组件的一部分)的一部分而结束了:

    setQuery(query){
        let obj = Object.assign({}, this.$route.query);

        Object.keys(query).forEach(key => {
            let value = query[key];
            if(value){
                obj[key] = value
            } else {
                delete obj[key]
            }
        })
        this.$router.replace({
            ...this.$router.currentRoute,
            query: obj
        })
    },

    removeQuery(queryNameArray){
        let obj = {}
        queryNameArray.forEach(key => {
            obj[key] = null
        })
        this.setQuery(obj)
    },

1

我通常为此使用历史对象。它还不会重新加载页面。

例:

history.pushState({}, '', 
                `/pagepath/path?query=${this.myQueryParam}`);

0

这是我无需刷新页面即可更新URL中的查询参数的简单解决方案。确保它适用于您的用例。

const query = { ...this.$route.query, someParam: 'some-value' };
this.$router.replace({ query });
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.