Rendering VUE router links with v-for - vue.js

i want to create an app that renders links dynamically with v-for and opens different components with each link.
I know how to render the <router-link> itself ,But I don't know how to dynamically change the destination url of the to="" prop.

If your array looks for example like this:
components: [
{
path: "/a",
name: "Component A"
},
{
path: "/b",
name: "Component B"
}
]
You can use it in v-for like:
<router-link
v-for="(comp, i) in components"
:key="i"
:to="{ path: comp.path }"
>
{{comp.name}}
</router-link>

You can achieve this using bind :to="{path: '/to'}" in <router-link>.

Related

Nav items having active class even when I change

I am facing this issue with navigation. Whenever I switch the tabs, the route with "" keeps being active all the time no matter what. I tried using router-exact css, but whenever I go in nested route then the menu nav stops having active class. I believe this is because the path is ""
Router:
{
path: "",
name: "Item1",
component: Item
}
Component
<router-link :to="{ name: 'Item1' }" >Item1</router-link>
<router-link :to="{ name: 'Item2' }" >Item2</router-link>
<router-link :to="{ name: 'Item3' }" >Item3</router-link>
The lighter color is active class
How it looks
Set path to '/' and add exact or exact-path to links: <router-link exact :to="{...}">
Here is the official documentation: https://router.vuejs.org/api/#exact

What would be the best way to use vue routes?

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>

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.

How does Vue router-link get its parameters?

I have vue router config with routes like this:
{
path: '/:language/:url/filter/',
name: 'search-filter',
component: SearchFilter,
meta: { removeScroll: true }
}
{
path: '/:language/:url/map/',
name: 'search-map',
component: SearchMap,
meta: { removeScroll: true }
}
Whenever I place a router-link with that component like so:
<router-link :to="{ name: 'search-map' }">
<svg-inline name="beacon-circle"></svg-inline>
{{ trans.hotel.show_map }}
</router-link>
It generates a full route to the named route of search-map. Now I have not manually passed in parameters to the <router-link>. It seem to grab the route parameters from the current component to generate the route parameters for the named route url.
I can not find anything about this in the Vue.js documentation about the fact that this is being done automatically.
If I inspect the router-link component with the Vue devtools it does have a props object which contains a to object which holds the parameters. I can't seem to find any documentation on this though.

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 }"