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.
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'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 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.
I'm building a menu app using Vue JS. I was told that only have to use 1 component if the styling stays the same. So that means i have to use dynamic data. each menu/submenu has 3 to 4 menu links. I was looking for a solution to send variables with data to a component and came up with 'props'. But i couldn't find a way to send props from different routes to the same component and check which route you're on to know which props to load into the html.
I already tried to load props into a template, and that works fine. But sending and replacing prop values in the same part of html is something i haven't figured out yet.
{ path: '/list', component: List, props: { url: 'www.google.com' } }
<template>
<div class="container">
<h1>Welkom</h1>
<div class="row">
<div class="col-md-6">
<router-link to='/weed'>Wiet</router-link>
</div>
<div class="col-md-6">
<router-link to='/stuff'>Stuff</router-link>
</div>
<div class="col-md-6">
<router-link to='/joint'>Joint</router-link>
</div>
<div class="col-md-6">
<router-link to='/edibles'>Edibles</router-link>
</div>
</div>
</div>
</template>
the <router-link> should dynamic depending on which route you are, so it can load in different menu items.
I want a menu that loads in different route links depending on which route you are.
I think you should use Programmatic Navigation and query params like
router.push({ path: 'register', query: { plan: 'private' } })
so for your application use
<div class="col-md-6"
#click="$router.push({ path: '/edibles',
query: { url: 'www.google.com', other: 'etc' }})"
>Edibles</div>
you can access these query params in the navigated component using $route.params.url in a template and this.$route.params.url in functions and computed and all other properties of vue component instance.
also check https://router.vuejs.org/guide/essentials/navigation.html for details
Edit as per comment
I think you should still use Programmatic Navigation with
router.push({ name: 'user', params: { userId } })
the params provided can be used as props to the component as shown below
const User = {
props: ['id'],
template: '<div>User {{ id }}</div>'
}
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User, props: true }
]
})
just remember to set props: true in routes definition!
You can use params from your route as props in your component and use a watcher to react to route changes. Either have a state system (vuex) with which you can access specific data regarding the params or just plainly use the params.
Use: router.push({ path: '/user/${userId}' })
then
watch: {
$route(to, from) {
// react somehow
}
}
and/or
template: '<div>User {{ $route.params.id }}</div>'
A the root of my app I have a "demo" route to a module that handles all the demos on the site:
{
path: 'demo',
canActivate: [AuthGuardService],
loadChildren: './demo/demo.module#DemoModule'
}
Then, in the demo module's routing module I have all the demos, some of which are also modules, such as
{
path: 'splitviews',
loadChildren: './splitviews/splitviews.module#SplitviewsModule'
}
Which is a module of demos of types of "Splitviews", components with 2 named route outlets: 1 for the left nav and 1 for the content:
<app-header class="site-header"></app-header>
<div class="site-content"></div>
<div [ngClass]="containerType"
class="splitview-wrapper">
<div class="row">
<div class="col-sm-2"">
<router-outlet name="leftnav"></router-outlet>
</div>
<div class="col-sm-10">
<router-outlet name="content"></router-outlet>
</div>
</div>
</div>
<app-footer class="site-footer"></app-footer>
So far, this module has routing like this
path: 'basic',
component: SplitviewsComponent,
data: {
containerType: 'container'
},
children: [
{
path: '',
component: LeftnavBasicComponent,
outlet: 'leftnav'
},
{
path: '',
component: Content1Component,
outlet: 'content'
}
]
},
So now if you went to /demo/splitviews/basic you'd see the splitviews component with the header, footer, and the 2 route outlets displaying LeftnavBasicComponent and Content1Component.
But now what I need to do is have the links in the LeftnavBasicComponent load different content components (e.g. Content2Component) inside the router-outlet "content". And I'm not sure how to best configure those sub-routes.
You can use the LeftnavBasicComponent and Content1Component as placeholders and then the components you really want to show will be loaded inside them depending on a value you'll pass by url.
Your html will be like below
<app-header class="site-header"></app-header>
<div class="site-content"></div>
<div [ngClass]="containerType"
class="splitview-wrapper">
<div class="row">
<div class="col-sm-2"">
<app-leftnav></app-leftnav>
</div>
<div class="col-sm-10">
<app-content></app-content>
</div>
</div>
</div>
app-leftnav and app-content are respectively the selectors of LeftnavBasicComponent and Content1Component.
The routing module will simply look like below:
{
path: 'basic/:leftnavtype/:contenttype',
component: SplitviewsComponent,
data: {
containerType: 'container'
}
}
Now in the LeftnavBasicComponent typescript file we have to take the value of leftnavtype from the url and put it in a variable like below:
leftNavType: string;
ngOnInit() {
this.route.params.subscribe((params: Params) => {
this.leftNavType = params["leftnavtype"];
});
}
And finally in the LeftnavBasicComponent html file we show a specific component depending on the leftNavType value
<app-type-1-left-nav *ngIf="leftNavType==='type1'"></app-type-1-left-nav>
<app-type-2-left-nav *ngIf="leftNavType==='type2'"></app-type-2-left-nav>
The same will be done for the content placeholder.
After doing so, if you call /demo/splitviews/basic/type1/content3, the type1 component will be loaded in the left nav placeholder and the content3 component will be loaded in the content placeholder, and you can then generate the link you want in the navigation part to load a specific component in the content part.
It may not be the perfect solution, but it works in your case.
And if there is only few cases, I suggest simply creating a route for each one, both solutions work depending on your needs.
Happy to clarify more if needed!