如何设置URL查询参数在Vue与Vue路由器

我试图在改变输入字段时用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 },
]
})
374554 次浏览

下面是文档中的例子:

// 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对于路由器是可选的——一些用于构造视图的组件的附加信息
  • namepath是必须的——它决定在你的<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'}})

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

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

为了一次设置/删除多个查询参数,我最终使用了以下方法作为全局mixins的一部分(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'})来在窗口中使用查询参数推入当前位置。历史堆栈。

要将查询参数添加到当前位置没有推动新的历史项,请使用history.replaceState代替。

用Vue 2.6.10和Nuxt 2.8.1测试。

< p > 使用这种方法要小心! < br > 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)。

上面的答案很接近……不过是客体。赋值它会改变这个。$route。当执行Object.assign时,确保第一个参数是{}

this.$router.push({ query: Object.assign({}, this.$route.query, { newKey: 'newValue' }) });

我通常使用history对象。它也不会重新加载页面。

例子:

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路由器在更新时不断重新加载页面,最好的解决方案是

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

好吧,所以我一直试图添加一个参数到我现有的url wich已经有一个星期的params现在lol, 原始url: http://localhost:3000/somelink?param1=test1 我一直在尝试:

this.$router.push({path: this.$route.path, query: {param2: test2} });

此代码将删除param1并变成 http://localhost:3000/somelink?param2=test2 < / p >

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

this.$router.push({path: this.$route.fullPath, query: {param2: test2} });

现在我成功地在旧的参数和结果添加参数

http://localhost:3000/somelink?param1=test1&param2=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}})
}

这与使用Composition API是等价的

<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()


router.push({ path: 'register', query: { plan: 'private' }})
</script>

你也可以使用Vue devtools来确保它按预期工作(通过检查你所处的给定路由),如下所示:https://stackoverflow.com/a/74136917/8816585


更新

这将同时挂载/卸载组件。一些香草JS解决方案仍然是实现该目的的最佳方式。