导航到同一路由后,beforeEnter 添加的 Vue Router 路由查询参数丢失
Vue Router route query param added by beforeEnter lost after navigate into the same route
当导航到您当前所在的同一路线时,在进入路线守卫之前添加的路线查询page
丢失。
这是由于路由器 link to
对象不包含查询 page
,并且它在进入 hook[= 之前不进入 51=] 了,因为它已经在同一条路线上了。
我发现您可以将它添加到您的路由器推送或 link 按钮中,并且只要您知道视图包含查询 page
.
就需要添加它
示例:
this.$router.push({ name: 'routeName', query: { page: 1 } });
问题:
有没有一种优雅的方法可以在路由守卫中处理这个问题?
我应该使用哪个挂钩,以便即使用户导航到同一路线也可以保留路线查询 page
?
示例代码:
路线
// Sample route
const routes = [
{
path: 'test',
name: 'Test',
component: TestPage,
beforeEnter: testPageGuard,
},
];
路由守卫
// Test Page Guard
testPageGuard: (to, from, next) => {
const { page = null } = to.query;
let finalNext;
if (!page) {
finalNext = {
...to,
query: {
...to.query,
page: 1,
},
};
}
if (finalNext) {
next(finalNext);
} else {
next();
}
}
查看
// TestPage.vue
<template>
<!-- The problem can be reproduce when clicking this link
when you are already in route '/test' -->
<router-link :to="{ name: 'Test'}">
Test
</router-link>
</template>
<script>
export default {
name: 'Test',
};
</script>
解决方案:
- 将查询 页面 添加到路由器 link
// TestPage.vue
<template>
<!-- query page is added here -->
<router-link :to="{ name: 'Test', query: { page: 1 } }">
Test
</router-link>
</template>
<script>...</script>
我发现还有两种方法可以做到这一点。
解决方案一:在“beforeRouteUpdate”挂钩处更新
beforeRouteUpdate 在查询参数更改时触发,即使在同一路由中也是如此。
因此我们可以删除 beforeEnter 守卫和路由 link 中额外的 page
查询,并添加查询参数 page
在该特定页面。
示例代码
查看
// TestPage.vue
<template>
<!-- The problem can be reproduce when clicking this link
when you are already in route '/test' -->
<router-link :to="{ name: 'Test'}">
Test
</router-link>
</template>
<script>
export default {
name: 'Test',
// Solution here
beforeRouteUpdate(to, from, next) {
if (!Object.prototype.hasOwnProperty.call(to.query, 'page')) {
next({
...to,
query: {
// This line is used to retain other query if there is any
...to.query,
page: 1,
},
});
} else {
next();
}
},
};
</script>
解决方案 2:在“beforeEach”挂钩处更新
即使在同一路由中查询参数发生变化,它实际上也会通过 beforeEach 挂钩。
因此我们可以删除 beforeEnter 守卫和路由 link.
中额外的 page
查询
为该路由添加元标记 hasQueryParamPage
并在全局 beforeEach 挂钩中添加查询参数 page
。
如果您有其他页面需要查询参数 page
.
,此设计具有更好的可重用性
示例代码
路线
// Sample route
const routes = [
{
path: 'test',
name: 'Test',
component: TestPage,
// add meta tag
meta: { hasQueryParamPage: true },
},
];
路由器
// router.js
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
...
});
// Solution here
router.beforeEach((to, from, next) => {
if (to.matched.some((record) => (record.meta.hasQueryParamPage))) {
let updatedNext = null;
if (!Object.prototype.hasOwnProperty.call(to.query, 'page')) {
updatedNext = {
...to,
query: {
// This line is used to retain other query if there is any
...to.query,
page: 1,
},
};
}
if (updatedNext) {
next(updatedNext);
return;
}
}
next();
});
当导航到您当前所在的同一路线时,在进入路线守卫之前添加的路线查询page
丢失。
这是由于路由器 link to
对象不包含查询 page
,并且它在进入 hook[= 之前不进入 51=] 了,因为它已经在同一条路线上了。
我发现您可以将它添加到您的路由器推送或 link 按钮中,并且只要您知道视图包含查询 page
.
示例:
this.$router.push({ name: 'routeName', query: { page: 1 } });
问题:
有没有一种优雅的方法可以在路由守卫中处理这个问题?
我应该使用哪个挂钩,以便即使用户导航到同一路线也可以保留路线查询 page
?
示例代码:
路线
// Sample route
const routes = [
{
path: 'test',
name: 'Test',
component: TestPage,
beforeEnter: testPageGuard,
},
];
路由守卫
// Test Page Guard
testPageGuard: (to, from, next) => {
const { page = null } = to.query;
let finalNext;
if (!page) {
finalNext = {
...to,
query: {
...to.query,
page: 1,
},
};
}
if (finalNext) {
next(finalNext);
} else {
next();
}
}
查看
// TestPage.vue
<template>
<!-- The problem can be reproduce when clicking this link
when you are already in route '/test' -->
<router-link :to="{ name: 'Test'}">
Test
</router-link>
</template>
<script>
export default {
name: 'Test',
};
</script>
解决方案:
- 将查询 页面 添加到路由器 link
// TestPage.vue
<template>
<!-- query page is added here -->
<router-link :to="{ name: 'Test', query: { page: 1 } }">
Test
</router-link>
</template>
<script>...</script>
我发现还有两种方法可以做到这一点。
解决方案一:在“beforeRouteUpdate”挂钩处更新
beforeRouteUpdate 在查询参数更改时触发,即使在同一路由中也是如此。
因此我们可以删除 beforeEnter 守卫和路由 link 中额外的 page
查询,并添加查询参数 page
在该特定页面。
示例代码
查看
// TestPage.vue
<template>
<!-- The problem can be reproduce when clicking this link
when you are already in route '/test' -->
<router-link :to="{ name: 'Test'}">
Test
</router-link>
</template>
<script>
export default {
name: 'Test',
// Solution here
beforeRouteUpdate(to, from, next) {
if (!Object.prototype.hasOwnProperty.call(to.query, 'page')) {
next({
...to,
query: {
// This line is used to retain other query if there is any
...to.query,
page: 1,
},
});
} else {
next();
}
},
};
</script>
解决方案 2:在“beforeEach”挂钩处更新
即使在同一路由中查询参数发生变化,它实际上也会通过 beforeEach 挂钩。
因此我们可以删除 beforeEnter 守卫和路由 link.
中额外的page
查询
为该路由添加元标记 hasQueryParamPage
并在全局 beforeEach 挂钩中添加查询参数 page
。
如果您有其他页面需要查询参数 page
.
示例代码
路线
// Sample route
const routes = [
{
path: 'test',
name: 'Test',
component: TestPage,
// add meta tag
meta: { hasQueryParamPage: true },
},
];
路由器
// router.js
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
...
});
// Solution here
router.beforeEach((to, from, next) => {
if (to.matched.some((record) => (record.meta.hasQueryParamPage))) {
let updatedNext = null;
if (!Object.prototype.hasOwnProperty.call(to.query, 'page')) {
updatedNext = {
...to,
query: {
// This line is used to retain other query if there is any
...to.query,
page: 1,
},
};
}
if (updatedNext) {
next(updatedNext);
return;
}
}
next();
});