我试图用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 },
]
})
为了一次设置/删除多个查询参数,我最终使用了以下方法作为全局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)
},
下面是文档中的例子:
// with query, resulting in /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})
裁判:https://router.vuejs.org/en/essentials/navigation.html
正如那些文档中提到的,路由器。Replace工作原理类似router.push
因此,您似乎在您的示例代码中有它的问题。但我认为你可能还需要包括名称或路径参数,这样路由器就有一些路由可以导航到。如果没有名称或路径,它看起来没有多大意义。
这是我现在的理解:
查询是可选的路由器-一些额外的信息组件构造的视图
名称或路径是必须的-它决定在<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"} })
从技术上讲,上面的和这个。$router没有区别。替换({path: "/user/123", query:{q1: "q1"}}),但是在命名路由上提供动态参数比组成路由字符串更容易。但在任何一种情况下,都应该考虑到查询参数。在这两种情况下,我都没有发现处理查询参数的方式有任何错误。
在你进入路由后,你可以获取动态参数,像这样。$route.params。Id和你的查询参数如下。$route.query.q1
如果您试图保留一些参数,同时更改其他参数,请确保复制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测试。