如何使用 Vue-Router 在 Vue 中设置 URL 查询参数
How to set URL query params in Vue with Vue-Router
我试图在更改输入字段时使用 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 },
]
})
这是文档中的示例:
// 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
所以,您的相关示例代码似乎是正确的。但我认为您可能还需要包含 name
或 path
参数,以便路由器有一些导航路径。没有name
或path
,看起来意义不大。
这是我目前的理解:
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
。
实际上你可以像这样推送查询:this.$router.push({query: {plan: 'private'}})
this.$router.push({ query: Object.assign(this.$route.query, { new: 'param' }) })
一次 set/remove 多个查询参数我最终使用以下方法作为我的全局混合的一部分(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)
},
无需重新加载页面或刷新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
如果您试图保留一些参数,同时更改其他参数,请务必复制 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 测试。
对于添加多个查询参数,这对我有用(从这里 https://forum.vuejs.org/t/vue-router-programmatically-append-to-querystring/3655/5)。
an answer above was close … though with Object.assign it will mutate this.$route.query which is not what you want to do … make sure the first argument is {} when doing Object.assign
this.$router.push({ query: Object.assign({}, this.$route.query, { newKey: 'newValue' }) });
我通常为此使用历史对象。它也不会重新加载页面。
示例:
history.pushState({}, '',
`/pagepath/path?query=${this.myQueryParam}`);
这是我在 URL 中更新查询参数而不刷新页面的简单解决方案。确保它适用于您的用例。
const query = { ...this.$route.query, someParam: 'some-value' };
this.$router.replace({ query });
我的解决方法,没有刷新页面也没有报错Avoided redundant navigation to current location
this.$router.replace(
{
query: Object.assign({ ...this.$route.query }, { newParam: 'value' }),
},
() => {}
)
您也可以只使用浏览器 window.history.replaceState
API。它不会重新安装任何组件,也不会导致冗余导航。
window.history.replaceState(null, '', '?query=myquery');
vue router 在更新时不断重新加载页面,最好的解决方案是
const url = new URL(window.location);
url.searchParams.set('q', 'q');
window.history.pushState({}, '', url);
好的,所以我一直在尝试向我现有的 url 添加一个参数,现在已经有一个星期的参数了,哈哈,
原文 url: http://localhost:3000/somelink?param1=test1
我一直在尝试:
this.$router.push({path: this.$route.path, query: {param2: test2} });
此代码将删除 param1 并变为
http://localhost:3000/somelink?param2=test2
为了解决这个问题,我使用了 fullPath
this.$router.push({path: this.$route.fullPath, query: {param2: test2} });
现在我成功地在旧参数上添加了参数,结果是
http://localhost:3000/somelink?param1=test1¶m2=test2
使用 RouterLink
//With RouterLink
<router-link
:to="{name:"router-name", prams:{paramName: paramValue}}"
>
Route Text
</router-link>
//With Methods
methods(){
this.$router.push({name:'route-name', params:{paramName: paramValue}})
}
有方法
methods(){
this.$router.push({name:'route-name', params:{paramName, paramValue}})
}
我试图在更改输入字段时使用 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 },
]
})
这是文档中的示例:
// 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
所以,您的相关示例代码似乎是正确的。但我认为您可能还需要包含 name
或 path
参数,以便路由器有一些导航路径。没有name
或path
,看起来意义不大。
这是我目前的理解:
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
。
实际上你可以像这样推送查询:this.$router.push({query: {plan: 'private'}})
this.$router.push({ query: Object.assign(this.$route.query, { new: 'param' }) })
一次 set/remove 多个查询参数我最终使用以下方法作为我的全局混合的一部分(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)
},
无需重新加载页面或刷新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.
如果您试图保留一些参数,同时更改其他参数,请务必复制 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 测试。
对于添加多个查询参数,这对我有用(从这里 https://forum.vuejs.org/t/vue-router-programmatically-append-to-querystring/3655/5)。
an answer above was close … though with Object.assign it will mutate this.$route.query which is not what you want to do … make sure the first argument is {} when doing Object.assign
this.$router.push({ query: Object.assign({}, this.$route.query, { newKey: 'newValue' }) });
我通常为此使用历史对象。它也不会重新加载页面。
示例:
history.pushState({}, '',
`/pagepath/path?query=${this.myQueryParam}`);
这是我在 URL 中更新查询参数而不刷新页面的简单解决方案。确保它适用于您的用例。
const query = { ...this.$route.query, someParam: 'some-value' };
this.$router.replace({ query });
我的解决方法,没有刷新页面也没有报错Avoided redundant navigation to current location
this.$router.replace(
{
query: Object.assign({ ...this.$route.query }, { newParam: 'value' }),
},
() => {}
)
您也可以只使用浏览器 window.history.replaceState
API。它不会重新安装任何组件,也不会导致冗余导航。
window.history.replaceState(null, '', '?query=myquery');
vue router 在更新时不断重新加载页面,最好的解决方案是
const url = new URL(window.location);
url.searchParams.set('q', 'q');
window.history.pushState({}, '', url);
好的,所以我一直在尝试向我现有的 url 添加一个参数,现在已经有一个星期的参数了,哈哈,
原文 url: http://localhost:3000/somelink?param1=test1
我一直在尝试:
this.$router.push({path: this.$route.path, query: {param2: test2} });
此代码将删除 param1 并变为
http://localhost:3000/somelink?param2=test2
为了解决这个问题,我使用了 fullPath
this.$router.push({path: this.$route.fullPath, query: {param2: test2} });
现在我成功地在旧参数上添加了参数,结果是
http://localhost:3000/somelink?param1=test1¶m2=test2
使用 RouterLink
//With RouterLink
<router-link
:to="{name:"router-name", prams:{paramName: paramValue}}"
>
Route Text
</router-link>
//With Methods
methods(){
this.$router.push({name:'route-name', params:{paramName: paramValue}})
}
有方法
methods(){
this.$router.push({name:'route-name', params:{paramName, paramValue}})
}