我试图用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 },
  ]
})

当前回答

无需重新加载页面或刷新dom,历史记录。pushState可以做这个工作。 在你的组件或其他地方添加这个方法:

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

因此,在组件的任何地方,调用addParamsToLocation({foo: 'bar'})在窗口中推当前位置的查询参数。历史堆栈。

要将查询参数添加到当前位置,而不推入新的历史记录项,请使用history。replaceState代替。

用Vue 2.6.10和Nuxt 2.8.1测试。

使用这种方法要小心! Vue路由器不知道url已经改变,所以它不会在推送状态后反映url。

其他回答

为了一次设置/删除多个查询参数,我最终使用了以下方法作为全局mixins的一部分(这指向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)
    },
this.$router.push({ query: Object.assign(this.$route.query, { new: 'param' }) })

vue路由器在更新时不断重新加载页面,最好的解决方案是

  const url = new URL(window.location);
  url.searchParams.set('q', 'q');
  window.history.pushState({}, '', url);
        

我的解决方案,没有刷新页面,没有错误避免多余的导航到当前位置

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

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

这是有效的,因为你正在创建一个未引用的副本:

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

而下面会导致Vue Router认为你在重复使用相同的查询,并导致navigationduplication错误:

  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测试。