I have parent component which has
<router-view></router-view>
Inside of parent component there is another component and it also has a
<router-view></router-view>
Both are bound to /login route
When I go to /login route it loads both of them. I would like to skip first/parent router-view for loading the component.
How can i achieve this? I can think of setting some state and prevent loading with v-if directive but that seems kind of wrong.
Maybe another solution, can i pass null to a parent named view on specific route?
Found a solution in case of somebody needs:
<-- applies only this one -->
<router-view name="login"></router-view>
<router-view></router-view>
const router = new VueRouter({
routes: [
{
path: '/',
components: {
login: LoginComp
}
}
]
})
Ref : https://router.vuejs.org/en/essentials/named-views.html
Related
I'm a newbie to Vuejs and I'm wondering how I can load the component to App.vue depending on the route visited.
In my router -> index.js I have:
import { createRouter, createWebHistory} from 'vue-router'
import Events from '../views/Events.vue'
const routes = [
{
path: '/',
name: 'events',
component: Events
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default router
In my App.vue I have a template that I want to use for the entire website, so I thought to load the template here instead of loading it into each component.
My template has 1 box in the center of the screen, so the content changes depending on which route the user goes to.
Instead of calling the component content from the routes file, is there a better way to load it dynamically into App.vue depending on the route visited?
I could hard code it in App.vue with something like:
<template>
<Events />
</template>
<script>
import Events from './views/Events.vue'
export default defineComponent({
components: {
Events
},
</script>
But that won't solve my problem about the Events component being loaded dynamically depending on which route is visited. Is there a way to access the underlying component with something like this.$route to load the component instead of hard coding it.
The router-view component will render the component based on its path :
<template>
<router-view/>
</template>
<script>
export default defineComponent({
})
</script>
I don't know I'm about quite Vue, spent a day learning all hooks routes, tried throug regular hooks created, mounted and it still gives me null. Here is my component App where all other components are plugged in. I'm calling here mounted hook, so
basically it totally rendered this component, and we have a path + I wrapped evrythin in $nextTick just to be sure and it still returns me null name of a current router if I come to the website not from main url, but from children as for instance url/boys. I gave up long time ago getting this name of a router in children component where I need it, thought alright I'll just path it to children <the-nav/> that's where I need it. But it doesnt work event in parent and I need only name of a current router when I enter the website. That's it, sounds easy but went throught hell.
<template>
<div id="app">
<the-header/>
<the-nav/>
<div id="app__inner">
<transition name="fade" mode="out-in">
<router-view />
</transition>
</div>
</div>
</template>
<script>
import TheHeader from "#/components/TheHeader.vue";
import TheNav from "#/components/TheNav.vue"
export default {
components : {
TheHeader,
TheNav
},
mounted()
{
this.$nextTick(() => {
console.log(this.$router.currentRoute.name);
})
}
}
</script>
You can actually use the exposed router functions inside this befoureRouteEnter function, used like so:
beforeRouteEnter (to, from, next) {
console.log(to.name);
next();
},
Please read some documentation on router Navigation guards:
https://router.vuejs.org/guide/advanced/navigation-guards.html
Make sure you have the name set on the router, otherwise name will be undefined. For example...
const routes = [
{
path: "/",
component: Home,
name: "Home" // Make sure route is named
},
];
Then in component you should be able to access the name in mounted hook, without nextTick (like mentioned in comment):
mounted() {
alert(`Route name is: ${this.$route.name}`);
}
DEMO
So I have three pages in my app. In my folder structure, I have something like this:
/verify
---complete.vue
---business.vue
---personal.vue
verify.vue
so basically verify.vue has a <nuxt-child> component that deals with my business.vue and personal.vue. What I want to happen is complete.vue even inside the parent route of /verify/complete, will be having a different layout/page template.
Is there any way to achieve this? Thanks.
I was able to fix the problem with extendRoutes in nuxt.config.js. What this does is it adds a custom route without using the folder structure. So when the /verify/complete is hit, it will resolve the component.
router: {
middleware: ['auth'],
base: '/beta/',
extendRoutes(routes, resolve) {
routes.push({
name: 'verify-complete',
path: '/account/verify/complete',
component: resolve(__dirname, 'pages/account/verify-complete.vue')
})
}
}
The idea is to track current route through $route.fullPath, and if i'ts /verify/complete, then change layout appropriately. Lets consider this markup:
verify.vue:
<template>
<section>
<h1 v-if="$route.fullPath === '/verify/complete'">Complete</h1>
<h1 v-else>Business or Personal</h1>
<nuxt-child></nuxt-child>
<section>
</template>
If it's more complicated thah changing some block, tha you should define different pages components, and load them appropriately throug <component :is="COMPONENT_NAME">:
verify.vue:
<template>
<component :is="COMPONENT_NAME"></component>
</template>
I would like to use the same route to display different components based on whether or not the client is authenticated. I am unable to find info on this in the router documentation. Here is the same question but the answer seems to be outdated as router.map is deprecated.
Vue.js - two different components on same route
Please point me in the right direction,
thank you!
I'm not sure if dynamic routing within the router itself is supported at this time. An alternative is to load a wrapper component in your router. Then that component determines what nested components to show.
routes: [
{
path: '/',
component: WrapperComponent
}
]
<!-- WrapperComponent -->
<template v-if="auth">
<auth-view />
</template>
<template v-else>
<non-auth-view />
<template>
You can use mulitple components on a single path using named views :
example :
const router = new VueRouter({
routes: [
{
path: '/',
components: {
component1,
component2
}
}
]
})
<!-- this will display component1 on the path '/' -->
<router-view name="component1"></router-view>
<!-- this will display component2 on the path '/' -->
<router-view name="component2"></router-view>
In my vue application, how to place component (slot?) in the toolbar component?
My app for example:
<template>
<toolbar>…</toolbar>
<router-view />
</template>
and all the routes are lazy loaded.
for some routes I want to place component inside toolbar component. But I can't "insert" the component as slot. and to write the component and turn on/off with v-if seems to me wrong.
I think that I expect is
<div for="toolbar">This content should in toolbar</div>
<div for="router-view">This content for router-view</div>
Is there any way to solve this?
Vue Router Named Views will come in handy.
Sometimes you need to display multiple views at the same time instead
of nesting them, e.g. creating a layout with a sidebar view and a main
view. This is where named views come in handy. Instead of having one
single outlet in your view, you can have multiple and give each of
them a name. A router-view without a name will be given default as its
name.
A view is rendered by using a component, therefore multiple views require multiple components for the same route. Make sure to use the components (with an s) option:
<template>
<toolbar><router-view name="toolbar"></router-view></toolbar>
<router-view />
</template>
const router = new VueRouter({
routes: [
{
path: '/',
components: {
default: YourAwesomeComponent,
toolbar: YetAnotherAwesomeComponent
}
},
{
path: '/home',
components: {
default: YourAwesomeHomeComponent,
toolbar: YetAnotherAwesomeComponentThatSouldBeInToolbarOnHomePage
}
}
]
})