vue.js - 使用具有多个路由的相同组件,具体取决于路径组件类型
问题描述
我正在尝试将一个组件用于多个路由,但根据路径组件的类型,必须执行不同的操作。我有三个主要观点:
LevelOneView
:这是登录页面,仅显示搜索小部件。设置查询后,它会重定向到/search
路径并将查询存储在VueX
LevelTwoView
:此视图显示查询的结果。用户点击结果后,会将他们带到/:id
路径LevelThreeView
:此视图显示列表的详细信息
这三个视图需要共享一些路径。思路如下:
/search
=> 去LevelTwoView
,没有特别的工作/:city
=>可以插入位置 (london
, , ...),它应该转到已设置查询的位置,以仅搜索该地区可用的列表。网址应该是newyork
LevelTwoView
/search
/:id
=> 转到LevelThreeView
使用id
fetch req 的参数。这是一个数字
我在路由上设置了一个beforeEnter
守卫,/:city
以便它检查路径参数是否是数字,在这种情况下它应该重定向到LevelThreeView
. 如果我从/search
路径到/:id
(甚至直接/:id
从外部到路径),这工作正常,但如果我从 aLevelThreeView
到 aLevelThreeView
它不起作用并返回此错误:
Uncaught (in promise) undefined
eval @ vue-router.esm.js?8c4f:2051
abort @ vue-router.esm.js?8c4f:2082
eval @ vue-router.esm.js?8c4f:2131
beforeEnter @ router.js?41cb:43
iterator @ vue-router.esm.js?8c4f:2120
step @ vue-router.esm.js?8c4f:1846
eval @ vue-router.esm.js?8c4f:1847
eval @ vue-router.esm.js?8c4f:2139
eval @ main.js?56d7:115
iterator @ vue-router.esm.js?8c4f:2120
step @ vue-router.esm.js?8c4f:1846
step @ vue-router.esm.js?8c4f:1850
runQueue @ vue-router.esm.js?8c4f:1854
confirmTransition @ vue-router.esm.js?8c4f:2147
transitionTo @ vue-router.esm.js?8c4f:2034
push @ vue-router.esm.js?8c4f:2365
eval @ vue-router.esm.js?8c4f:2779
push @ vue-router.esm.js?8c4f:2778
goToListing @ ListingCard.vue?6c5e:147
click @ ListingCard.vue?917d:18
invokeWithErrorHandling @ vue.runtime.esm.js?2b0e:1854
invoker @ vue.runtime.esm.js?2b0e:2179
original._wrapper @ vue.runtime.esm.js?2b0e:6911
我通过以下方式设置路由器:
export default new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/',
name: 'LevelOne',
component: LevelOneView,
beforeEnter: (to, from, next) => {
// Clear the query
store.commit('resetQuery');
return next();
}
},
{
path: '/search',
name: 'LevelTwo',
component: LevelTwoView
},
{
path: '/:city',
name: 'LevelTwoWithCity',
component: LevelTwoView,
beforeEnter(to, _, next) {
// Strip the leading slash
let toPath = to.path.replace("/", "").toLowerCase();
// Check if the path is a number and push the lv3 view
if (!isNaN(toPath)) {
console.log("Router: found valid path for lv 3")
const id = parseInt(toPath);
console.log(id);
return next({name: 'LevelThree', params: { id: id }});
}
// Load up the query
let query = store.getters.getQuery;
// Get the name of all the regions, as a list, to lower case
let regions = query.regions.map(el => el.name.toLowerCase());
// Check if we have a matching one
if (regions.includes(toPath)) {
// First, deactivate them all
query.regions.map(el => el.value = false)
// Then, activate only the one that matched
query.regions.filter(el => el.name.toLowerCase().includes(toPath)).map(el => el.value = true);
// Commit the query
store.commit('setQuery', query);
}
return next();
}
},
{
path: '/:id',
name: 'LevelThree',
component: LevelThreeView,
beforeEnter(to, from, next) {
console.log("Inside Level3 beforeEnter");
next();
}
},
{
path: '/not-found',
name: '404',
component: NotFound,
},
{
path: '*',
name: '404',
component: NotFound,
},
]
})
我是这方面的初学者,所以我可能会犯一个微不足道的错误。如果有人可以给我任何指示,将不胜感激。
谢谢!
解决方案
最后,我已经能够找到一个“解决方法”。对于每个路由,您可以定义aliases。所以我更改了代码以使用它们,并在启动时加载所有可能的路线:
// Generate the aliases
let cities = myCities.map(el => "/" + el.name.toLowerCase());
// Get the base case (i.e. the first element to have something to match against)
let baseCity = cities.splice(0, 1)[0];
export default new Router({
...
routes: [
{
path: '/',
...
},
{
path: '/search',
...
},
{
path: baseCity,
name: 'LevelTwoWithCity',
component: LevelTwoView,
alias: cities,
... // Here I set up the query object to be passed on
},
{
path: '/:id',
name: 'LevelThree',
component: LevelThreeView
},
{
path: '*',
name: '404',
component: NotFound,
},
]
})
理论上,这可以使用此处addRoutes()
描述的方法动态实现
推荐阅读
- tomcat - 使用 bitbucket 管道部署战争
- python - ModuleNotFoundError:没有名为“win32crypt”的模块
- vulkan - 在vulkan中同步顶点缓冲区?
- ms-access - Microsoft Access 空白不是空白
- javascript - 如何访问子类组件模板中的超类属性?角
- dart - TextField 点击更改 Flutter 中的切换
- android - 如何在 Firebase Firestore 中使用查询
- python - 如何在odoo上重新创建失败的邮件
- flutter - FloatingActionButton onPressed 未触发
- c - 读取键值对的 fscanf 问题