I am using Vue-router and I was needing to use a nested route, so what I did I wrote Children Key word to reference for a child component page, so my problem is when I click on Link my current URL replaced with nested route and with an ID but not load my component, and when I change Router-Linke to another component that is not nested it will load component, so I ask what are my mistakes?
route.js
{
path: '/targets',
name: 'target',
component: () =>
import ( /* webpackChunkName: "target" */ '#/views/admin/Target.vue'),
meta: {
middleware: [
auth
],
title: "Targets"
},
children:[
{
path: '/targets/:id/details',
name: 'target-details',
props: true,
component: () =>
import ( /* webpackChunkName: "target" */ '#/views/admin/TargetDetails.vue'),
meta: {
middleware: [
auth
],
title: "TargetDetails"
}
},
]
},
target.vue
<template>
<div>
<li class="clearfix" v-for="domain in domains" :key="domain.domain_id">{{ domain.domain }}
<router-link class="more"
:to="{
name: 'target-details',
params: {
id: domain.domain_id
}
}" >Target details <i class="fa fa-angle-right"></i>
</router-link>
</li>
</div>
</template>
TargetDetails.vue
<template>
<div class="page-output">
<h1>Target Details</h1>
</div>
</template>
Nested routes are designed to facilitate component nesting (look at the 1st "picture")
You need to include <router-view> in your target.vue component...
If you don't want content of TargetDetails.vue rendered inside target.vue, dont use children config and make a target.vue top level route instead.
Related
So Iv'e tried to nest my routes unsuccessfully using Vue router.
{
path: '/admin',
name: 'Admin', component: () => import('pages/Admin'),
children:[
{ path: 'stock', name: 'Stock', component: ()=> import('pages/Stock')},
]},
It did not work so I found out that I need to put inside the parent component.
Now it works but if I load the page /admin/stock it renders the two componets. one on top of the others.
Why the parent component (/admin page) is still displayed?
Btw when I did the same thing without nesting the routes it worked perfectly fine and the components rendered seperatly(the snippet below).
{
path: '/admin',
name: 'Admin', component: () => import('pages/Admin'),
children:[
//no nested route
]},
{ path: 'admin/stock', name: 'Stock', component: ()=> import('../pages/Stock')},
Thanks for the help
You should include in "Admin" component a router-view tag. Admin component will work as a "layout" and it will render the children corresponding to the current route.
In example
Admin Component:
<template>
<div>
<div>
Content present in all childrens
</div>
<router-view>
<div>"Admin" page content</div>
</router-view>
</div>
</template>
Stock component:
<template>
<div>
"Stock" content
</div>
</template>
When you go to /admin
It will render:
<div>
<div>
Content present in all childrens
</div>
<div>"Admin" page content</div>
</div>
When you visit /admin/stock
It will render:
<div>
<div>
Content present in all childrens
</div>
<div>"Stock" content</div>
</div>
Here you have a better example
https://router.vuejs.org/guide/essentials/nested-routes.html
If you don't need reuse "Admin" component layout, you could use routes as you mentioned in the second case, without nesting them
I have created a sort of First page for my project, but I don't know why it renders everything twice on my page:
here is my First.vue component that is used by the router as the first page:
<template>
<h1>Bienvenue</h1>
<router-view></router-view>
<div class="routing" v-if="this.$route.path == '/'">
<router-link to='/app'>Go to application</router-link>
<br>
<router-link to='/test'>Go to test</router-link>
</div>
</template>
and here is what I get on the page when I npm run serve
Does anyone knows where it comes from?
UPDATE
When I delete the router-view element, the components appear once but when I click on one of the links, it changes the URL of the page but the page in itself is not showing the component.
And when I try to put everything in my router-view, like this:
<template>
<router-view>
<div class="routing" v-if="this.$route.path == '/'">
<h1>Bienvenue</h1>
<router-link to='/app'>Go to application</router-link>
<br>
<router-link to='/test'>Go to test</router-link>
</div>
</router-view>
</template>
it appears once, but like the other case, when I click on a link, it is just changing the URL and not the page.
Here is my index.js to show you how my routes are defined:
import {createRouter, createWebHistory} from 'vue-router'
import App from '../App.vue'
import Test from '../Views/Test.vue'
import First from '../Views/First.vue'
export const router = createRouter({
history: createWebHistory(),
routes: [
{
path:'/',
name: 'First',
component: First,
},
{
path:'/test',
name: 'Test',
component: Test
},
{
path:'/app',
name: 'App',
component: App
}
]
})
Just to clarify what results I expect from my app:
When I run the project, I want to launch on a page with just a header saying 'Hello' at the top of the page and two links where I can either click on 'Go to the application' or 'Go to test'.
Then, when I click on one of the links, I want to see the content of the component (so either test or the app), but I don't want to see the header and the links anymore.
I am not sure but try this:
{
path: "/app",
component: () => import("../App.vue"),
name: "App"
},
{
path: "/test",
component: () => import("../Views/Test.vue"),
name: "Test"
},
{
path: "/",
component: () => import("../Views/First.vue"),
name: "First"
}
Update with sample code or you can refer to live code here.
// App.vue
const First = {
template: `<div class = "container" id="app">
<h1>Hi from First</h1>
<hr>
<router-link to="/foo">Foo</router-link>
<router-link to="/bar">Bar</router-link>
</div>
`
}
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }
const routes = [
{
path:'/',
name: 'First',
component: First,
default: First
},
{
path:'/foo',
name: 'Foo',
component: Foo
},
{
path:'/bar',
name: 'Bar',
component: Bar
}
]
const router = new VueRouter({
routes
})
const app = new Vue({
router
}).$mount('#app')
// main.js
<div id="app">
<!-- route outlet -->
<!-- component matched by the route will render here -->
<router-view></router-view>
</div>
I'm using vue with vue-router and route doesn't work when routing to children route.
{
path: '/user',
name: 'User',
component: User,
children: [
{
path: 'profile',
component: Profile,
},
],
}
Programmatically routing to /user/profile
<template>
<div>
<button #click="goToUserProfile()">create new</button>
</div>
</template>
<script>
export default {
methods: {
goToUserProfile() {
this.$router.push('/user/profile') // Routing doesn't work
.catch(console.log);
},
},
};
</script>
give a route name "Profile" for "/user/profile"
{
path: '/user',
name: 'User',
component: User,
children: [
{
path: 'profile',
name: "Profile",
component: Profile,
},
],
}
navigation use route name
this.$router.push({name: "Profile"});
your User component should declare like this
User.vue
<template>
<div>
<p>this is user component</p>
<!-- your Profile component will replace this route-view -->
<route-view />
</div>
</template>
demo
https://codesandbox.io/s/falling-bash-6dl7m
Do your ensure that you put <router-view></router-view> in User Component template to make the nested (children) routes displayed.
<template>
<div>
<button #click="goToUserProfile()">create new</button>
<router-view></router-view> <!-- placeholder for children routes -->
</div>
</template>
Then you can access by both
this.$router.push('/user/profile') and this.$router.push({ name: 'UserProfile' })
As Vue router document states:
To render components into this nested outlet, we need to use the children option in VueRouter.
https://router.vuejs.org/guide/essentials/nested-routes.html
Hope this help.
I'm using VueJS's own router component. In my admin interface, there is one page which shows an overview list and another one with specific options for one single entry.
function configRoutes() {
return [
{
path: '/',
redirect: '/default',
name: 'Home',
component: TheContainer,
children: [
{
path: 'admin/viewerRoles',
name: 'List',
component: AdminViewerRoles,
children: [
{
path: ':id-:name',
name: 'Settings',
component: AdminViewerRoleSettings
}
]
}
]
}
]
}
With that approach, I can place a <router-view /> tag in my AdminViewerRoles component. This will render the details page as viewport. What I wonder is, if it is possible to render either of the views without giving up the syntactically correct, nested navigation approach.
My idea would be to place the <router-view /> tag and the normal page content in two different div elements and render them conditionally with v-if. But is that really the best approach?
This would be my idea (untested):
<template>
<div v-if="$route.params.id">
<router-view />
</div>
<div v-else>
<table>...</table>
</div>
</template>
can only a specific page be viewed via router-view?
App.vue
<div id="app">
<div class="out-page" v-if="$route.path === '/login'">
<router-view name="login"></router-view>
</div>
<div class="register-page" v-if="$route.path === '/register'">
<div class="register-wrapper">
<router-view name="register"></router-view>
</div>
</div>
<div class="in-page" v-if="$route.path === '/home'">
<div class="home-container>
<router-view name="home"></router-view>
</div>
</div>
</div>
router.js
export default new Router({
mode: "history",
routes: [
{
path: "/login",
name: "login",
component: () =>
import(/* webpackChunkName: "Login" */ "./pages/login.vue")
},
{
path: "/register",
name: "register",
component: () =>
import(/* webpackChunkName: "Register" */ "./pages/register.vue")
},
{
path: "/home",
name: "home",
component: () =>
import(/* webpackChunkName: "Home" */ "./pages/home.vue")
}
]
});
I need the router-view to enter only content from one particular page, not all of them. The name attribute does not work.
Is it possible to do this?
It's not entirely clear what you are trying to do, but normally, if you have only a single view on the page, the app structure would look more like this:
<div id="app">
<div class="shared-outer-class">
<router-view/>
</div>
</div>
The per view customization would be handled in the individual components themselves, or by some shared outer component if needed.
If you are intending to use multiple views on same page, then you might used named views. But that is not what your example seems to be trying to do.