What would be the best way to use vue routes? - vuejs2

I'm a bit new to Vue routes. I have a table in Home.vue and each row has a button in order to go to the details. I'll try to explain what I imagine. I want the redirection to open a new screen Overview with a sidebar that has 3 options: Overview, Commits and Files. My problem is to understand what should be the parent and what should the child. I'm sure that Commits and Files are children but should Overview be also a child or the parent of Commits and Files? The row that redirects to details:
<router-link :to="{ 'name': 'details', 'params': { 'tool': tool } }">{{id}}</router-link>
The routes that I currently have:
const DetailsChildren = [
{
path: 'commits/:tool',
name: 'commits',
component: commits
},
{
path: 'files/:tool',
name: 'files',
component: files
}
];
export default new Router({
routes: [
{
path: '/',
name: 'home',
component: Home
}
{
path: '/overview/:tool',
name: 'details',
component: details,
children: DetailsChildren
}
],
mode: 'history'
});
And DetailsChildren is as follows:
<template>
<div class="main">
<sidebar />
<router-view />
</div>
</template>
Currently DetailsChildren is Overview. But I think DetailsChildren should be the parent of Overview, Files and Commits and then I need to create another component Overview. But then I have two problems. First one is how I load Overview when I move from the table to DetailsChildren? The second one is that I want the route to be /overview/:tool. I'm a bit confused. What would be best way to handle the routes in this situation?

What you want to do is have three children under your details route, each with their own absolute path from /.
const DetailsChildren = [
{
path: '/overview/:tool',
name: 'overview',
component: overview
},
{
path: '/commits/:tool',
name: 'commits',
component: commits
},
{
path: '/files/:tool',
name: 'files',
component: files
}
];
This will create the following path mappings
/overview/:tool
Top-level component: details
Child component: overview
/commits/:tool
Top-level component: details
Child component: commits
/files/:tool
Top-level component: details
Child component: files
See the guide on Nested Routes.
You may think you can use an empty path for the overview route but this would then require the URL to have a trailing slash (ie /overview/tool/) and I figured you don't want that.
It's also recommended to remove the name from your details route and instead, link to the default child route (ie overview). Eg
<router-link :to="{ name: 'overview', params: { tool } }">{{id}}</router-link>
Otherwise, the router gets confused about which to display, the parent (empty) or child.
Your sidebar links can simply use the child route names to create their links, eg
<nav>
<ul>
<li>
<router-link :to="{name: 'overview'}">Overview</router-link>
</li>
<li>
<router-link :to="{name: 'commits'}">Commits</router-link>
</li>
<li>
<router-link :to="{name: 'files'}">Files</router-link>
</li>
</ul>
</nav>

Related

Vue-router v4: Nested route not matching with parent route

In this project I'm using Vue 3 (vite) and Vue-router v4 and trying to make routing work correctly.
I am trying to navigate to /escape-rooms/my-escape-room but the <router-link> object inside my menu does not get the class .router-link-active. In the main route /escape-rooms it does. I'm not sure what I'm doing wrong because the documentation states that nested routes automatically 'activate' any parent links with this class.
I have this list of routes:
const routes = [
{path: '/', name: 'main', component: Home},
{path: '/escape-rooms', name: 'escape-rooms', component: EscapeRooms},
{path: '/escape-rooms/:urlName', name: 'escape-room-item', component: EscapeRooms, props: true},
{path: '/contact', name: 'contact', component: Contact}
]
This is de part of my menu layout:
<div class="menu">
<div class="menuitem">
<router-link to="/contact">
contact
</router-link>
</div>
<div class="menuitem">
<router-link to="/escape-rooms">
escape-rooms
</router-link>
</div>
</div>
For anyone stumbling on the same issue. follow this article: https://github.com/vuejs/rfcs/blob/master/active-rfcs/0028-router-active-link.md#unrelated-but-similiar-routes

placing a router-view in template as a sub template this isn't working

When I place a route view in a template my vue router doesn't load the content, how can I load this?
In my homepage I've got
<router-view name="homepage"></router-view>
The code gets loaded perfectly from my vue router but the contained in the homepage template doesn't get loaded.
...
routes:
[
{
path: '/',
name: 'homepage',
components: {
homepage: HomepageTemplate,
subPart: subPartTemplate
}
}
]
...
homepageTemplate:
<template>
<div>
<router-view name="subPartTemplate"/>
</div>
</template>
You named the component subPart but are referencing to it as subPartTemplate;
<template>
<div>
<router-view name="subPart"/>
</div>
</template>
Edit: I see you edited your post; what's going wrong is you are using a child <router-view> without defining children in your routes;
You should define children in your path:
{
path: '/',
name: 'homepage',
component: HomepageTemplate,
children: [
{ path: '/', component: subPartTemplate }
]
}
Now the <router-view> in the homepageTemplate should be the subPartTemplate. No need to use named components for this. Named components are useful when you need multiple <router-view>'s in one template.
Checkout the documentation for more details.

Router Link only updates active class once

I am trying to use <b-nav-item> tags as router links but the active link class only updates one time – I can load the page and click on a nav item and the class changes appropriately. But clicking again does not.
I have tried various syntax for the link attributes including:
to="dashboard"
to="/dashboard"
:to="{ name: 'Dashboard' }"
:to="{ path: '/dashboard' }"
I've also tried adding the exact attribute tag. Nothing is working and I feel like I'm running in circles here. Any ideas?
CompanionNavigation:
<template>
<div>
<b-nav pills>
<b-nav-item :to="{ name: 'Dashboard'}" exact>Dashboard</b-nav-item>
<b-nav-item :to="{ name: 'Contacts' }" exact>Contacts</b-nav-item>
</b-nav>
</div>
</template>
Routes:
{
path: '/dashboard',
name: 'Dashboard',
component: Dashboard,
},
{
path: '/contacts',
name: 'Contacts',
component: Contacts,
},
This was resolved by removing the following from my main template file:
<!-- Load Vue followed by BootstrapVue -->
<script src="//unpkg.com/vue#latest/dist/vue.min.js"></script>
<script src="//unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.min.js"></script>

Vue Child is not loaded after route enter

This is my router structure
{
path: '/',
name: 'home',
component: Home
},
{
path: '/user/:id',
name: 'user',
component: User,
children: [
{
path: '',
name: 'page',
component: Page
},
.....
}
I used this in Home.vue to redirect (/user/12345)
<router-link
:to="{
name: 'user',
params: {id: user.userId}
}"
>
When I clicked this link in home page, it routes correct path however I can not render child component (Page.vue) However when I reload the page, child component is loaded successfully. (url is still same)
There is an only rendering issue when I click the link on the homepage. How can I get rid of this. Thanks in advance.
User.vue
<template>
<div>
<NavDrawer/>
<router-view></router-view>
</div>
</template>
Edit: Any help will be so beneficial for me. Thanks

Router link not calling router view on nested routes

I have a router
routes: [
{
path: '/',
name: 'home',
meta : {
label : 'Home'
},
component: Home
},
{
path: '/usuarios',
name: 'usuarios',
meta : {
label : 'Usuarios'
},
component: Users,
children : [
{
path: '/listar',
meta : {
label : 'Listar'
},
name : 'listUser',
component: Wrapper,
},
{
path: '/cadastrar',
meta : {
label : 'Cadastrar !'
},
name : 'userCreate',
component: UserCreate
},
],
},
]
And I have a template for rendering this router at my navbar
<div class="main">
<ul class="menu-list">
<li v-for="item in menus" v-on:click="toggleActive(item)">
<router-link class="font-gray" :to="item.path" :exact="true">{{item.meta.label}}</router-link>
<ul class="menu-list" v-if="item.children && item.isActive">
<li v-for="child in item.children">
<router-link class="font-gray" :to="{path : item.path+child.path}" :exact="true" :append="true" >{{child.meta.label}}</router-link>
</li>
</ul>
</li>
</ul>
</div>
When I click on the first router-link, the view is rendered with no problem at the router view. But when I click on the router link of childrens, it does not work,
Anyone have any idea why?
I finally figured it out.
If you have children, the father component should have a <router-view> as well
Found the answer here: Vue router2 not catching deep nested routes
Thanks everybody for trying help
This issue is happening because you have forward slashes / prepended to the paths of your nested routes.
From the documentation on nested routes:
Note that nested paths that start with / will be treated as a root path. This allows you to leverage the component nesting without having to use a nested URL.
This means that, even though your "listar" route is a child of your "usuarios" route, the path is /listar, not /usuarios/listar.
You should remove the forward slashes from the paths of your nested routes, and then specify the path in your template like so:
:to="{ path : item.path + '/' + child.path }"