How to use a component depending on the route - javascript

Hello I am currently doing the front end of my project.
I would like to render components dynamically depending on the route.
For example I have a /auth route then it links to /auth/login or /auth/register or /auth/forgot.
This is the place where I would like to see the different components rendered.
I was assuming I can use router-view to loud the different components into the DOM.
<template>
<head-comp></head-comp>
<router-view></router-view>
<footer-comp></footer-comp>
</template>
<script>
import HeaderComp from '../components/Universal/HeaderComp.vue'
import FooterComp from '../components/Universal/FooterComp.vue'
export default
{
components: {
'header-comp' : HeaderComp,
'footer-comp' : FooterComp
}
}
</script>
This is the router
{
path: '/auth',
name: 'auth',
component: () => import('../views/AuthView.vue'),
children: [
{
path: 'login',
name: 'auth.login',
component: () => import('../components/Authentication/LoginComp.vue')
},
],
}
And this is the vue file that will contain the login form.
<tempalte>
Login
</tempalte>
<script>
</script>
The error I get with my current approach is this.
The requested module '/src/components/Authentication/LoginComp.vue?vue&type=tempalte&index=0&lang.tempalte' does not provide an export named 'default'
I was thinking I could just use different views for example, login/registerView.vue instead of having them in components but I feel like this is messier and would make it harder to maintain in the future.
Thanks for reading and looking forward to your responses.

You have typos in your LoginComp.vue component.
<tempalte>
Login
</tempalte>
should be
<template>
Login
</template>

Related

The route is not working properly Angular

It doesn't do me the right thing, Url changes it but the page doesn't render it.
I have two home and jobs routes, I watched doc. From Angular, but not working
This is routing.module
import { Route, Routes, RouterModule } from '#angular/router';
import { NavigationJobsComponent } from './../jobs/navigation-jobs/navigation-jobs.component'
import { InputFieldComponent } from './components/input-field/input-field.component'
export const routes: Routes = [
{
path: "",
component: InputFieldComponent
},{
path: "jobs",
component: NavigationJobsComponent
},
];
This is dependency from module
RouterModule.forRoot(routes),
Surely someone has been hit by this before. Maybe this topic will be useful to someone, Excuse the emotions
"but the page doesn't render it"
It seems like you forgot to add <router-outlet></router-outlet> in your AppComponent's Template
Have created a Stackblitz Demo for your reference
As KShewengger has said above, look in your template if you're using the <router-outlet></router-outlet>. If you're using a navbar to navigate between routes, then you have to put the <router-outlet></router-outlet> in your navbar Component.
If not, try to use the <router-outlet></router-outlet> in your app.component.html (down if possible).
It would be nice if you could share your whole code about your issue, for better understand where could be it.

Vue, how can I render different navbar due to route?

I am new at Vue.js. I am working on demo project. In my project, I have three different navbar. First one for HomePage, second one for Login/Register page and third one is for Dashboard. In frameworks like React and Vue we set one global navbar for all pages. How can I render this three navbar components conditionally ? What is the best practice for that ? I want to set vuex for solve that, is that a right approach ?
You can do it using named routes. In your component you set multiple named router views:
<router-view name="navbar"></router-view>
<router-view ></router-view>
And in routes you set which component to render and where:
const router = new VueRouter({
routes: [
{
path: '/',
components: {
default: HomeContent,
navbar: HomeNavbar,
}
},
{
path: '/dashboard',
components: {
default: DashboardContent,
navbar: DashboardNavbar,
}
}
]
})
Otherwise you can set a conditional in the component and render navbar based on route:
if ($route.path === home) {
<NavbarHome />
}
If navbars have much in common you can just use a conditional for elements that are in one but not in another.
Actually what you can do is make a navbar component and use v-if to check on which route you are currently on. You can use the $route object to verify the current URL and use computed to check if the route name or params/queries are the same as you want.
computed: {
dashboard() {
return this.$route.name === 'Dashboard'
}
}
And then in your navbar component use v-if="dashboard" to check your conditions

Angular: Two outlets both without names still work

I cannot seem to figure out how this is working, I have an app with two router-outlet tags. Neither of the tags have a name associated with them, so how are the components displayed in the correct outlet?
const routes = [
{
path: 'login',
component: LoginComponent
},
{
path: 'user',
component: HomeComponent,
children: [
{
path: 'settings',
component: SettingsComponent
},
{
path: 'profile',
component: ProfileComponent
}
]
}
]
Then in the AppComponent template there is this, which shows the LoginComponent and the HomeComponent.
<header></header>
<main>
<router-outlet></router-outlet>
</main>
<footer></footer>
Then in the HomeComponent template there is this, which shows the SettingsComponent or ProfileComponent.
<ul class="nav"></ul>
<div class="content">
<router-outlet></router-outlet>
</div>
From what I have read, you need to have a named outlet and tell the route which outlet to render to. Why do I not need one here? This still works. What is happening? I cannot find a reasoning for this on Google other than to use a route with a name.
nested primary router outlets work fine and are very commonly used, in fact, it's the ONLY way parent / child routes can work.
With nested outlets, the router figures out what to render pretty intuitively, based on the parent / child structure of your route config.
You only need named outlets if they are siblings.

Vue.js passing array from one page to another

I'm using vue.js and I have one component, where the user selects what they want and then they hit "order". At this moment I use <router-link to="/order"> to show new page. But I don't know how to access the array from the previous component there. I tried something like this :selected-chairs="selectedChairs" and in the other component this props: ['selectedChairs'], but it doesn't work.
My routes file (index.js):
export default new Router({
routes: [
{
path: '/',
name: 'Select',
component: Select,
props: true
},
{
path: '/order',
name: 'Order',
component: Order,
props: true
}
]
})
It's possible to do what you want to do but I don't think it's a good idea. First, in line with your original question, this is what you could do:
Set up your order route:
export default new Router({
routes: [{
path: '/order/:selected-chairs',
name: 'Order',
component: Order,
props: true
}]
}
You could then have a link like so:
<router-link :to="'/order/' + JSON.stringify(mySelectedChairs) + '">Link Text</router-link>
or you could do
<router-link :to="{path: 'order', query: { selected-chairs: mySelectedChairs }}">Link Text</router-link>
This would allow you to access that data on your component using:
this.$route.params.selected-chairs
or
this.selectedChairs // because props: true binds to the props
This page has more information on passing params using router-link: https://router.vuejs.org/en/api/router-link.html
As I said, I don't think this is a good idea. Even if you're not using Vuex, you're much better off doing this using some sort of stateful component. You could then set the selected-chairs in your state and the order component would just know about them being selected. This allows you to do things like having a mini basket that reacts to users entering stuff into their baskets etc.
Setting up a simple Vuex system isn't complicated and there are various articles on the web to help that would be my recommended approach.
The above answer is correct but will show a blank page on page load.
To solve that, DO:
export default new Router({
routes: [{
path: '/order/:selected-chairs?',
name: 'Order',
component: Order,
props: true
}]
}
As you can see, I added a question mark (?) to the front of the path parameter

angular's equivalent to angularjs states

In AngularJS, for routing purposes, we define states with children which makes it possible to switch between views with the result that each view is always rendered in one container:
$stateProvider.state("communication.create-message", {
url: ...,
templateUrl: ...,
menu: ...,
parent: "communication",
ncyBreadcrumb: {
label: "Create Message"
}
});
Whichever state we choose - the view is always rendered within one container that has ui-view attribute.
I'm trying to achieve the same in Angular 2 or above, but I have no idea of how to reproduce the above-stated functionality.
In app.component.ts we have router-outlet where component templates get rendered.
Say, we have many nested child routes - is it possible to render all of them within this outlet ?
What would the code in app-routing.module.ts look like in this case ?
Could anyone please give a working example of how to go about it ?
Step 1 : Import Routes from #angular/router
in app.module.ts .. import Routes. You have to write
import {Routes} from '#angular/core'
Step 2 :
Add all the routes you want to set up in an array pf type Routes like :
this is for informing angular all the routes in your app. Each route is a javascript object in this array.
const appRoutes : Routes = [
{path : 'communication-route'}
]
always you have to give path , this what you enter after your domain like "localhost :4200/communication-route".
Step 3: Add the action to route i.e what happens when this path is reached.
const appRoutes : Routes = [
{path : 'communication-route'} , component :communicationroutecomponent
]
here i have given the component name "communicationroutecomponent" , i.e this component will be loaded when the path "/communication-route" is reached
Step 4: Register your routes in your app
To do this you will have to do new import in app.module.ts
import {RouterModule} from '#angular/router'
Routermodule has special method forRoot() which registers our routes .
In our case we will have to write this piece of code in
imports :[
RouterModule.forRoot(appRoutes)
]
Our routes are now registered and angular knows our routes now.
Step 5 : Where to display the route content i.e the html content of you route page.
For this angular has directive .
We need to include where we want to load our content i.e in the html.
<a router-outlet="/communication-route"></a>
Navigating to routes :
angular gives a directive for this routerLink
so if we want to navigate to users component , you can give this in your html element:
routerLink="/communication-route"
I hope i was able to explain how this works.
Your code should be as follows
export const ComRoute: Routes = [
{
path: 'communication-route',
children: [
{ path: 'communication', component: communicationComponent },
{ path: ':child1', component: child1Component },
{ path: ':child1/field', component: child1Component}
]
}
];
First of all, states are not an official AngularJS concept. They come from ui-router, which began life as an alternate to the simplistic built in router.
Eventually, ui-router became the de facto standard for routing in AngularJS while the official ng-route module was extracted into a separate, optional library by the Angular team.
ui-router, is complex but exceptional and has earned what is in my view well deserved popularity and success. This success has led to its expansion to support additional platforms enabling the same powerful state based structure in applications written for frameworks such as React.
It is now available for Angular (formerly known as Angular 2).
You can read the documentation and see how to get started on https://ui-router.github.io/ng2
Here is a snippet from the src/app/app.states.ts module of the official example repository
export const loginState = {
parent: 'app',
name: 'login',
url: '/login',
component: LoginComponent,
resolve: [
{ token: 'returnTo', deps: [Transition], resolveFn: returnTo },
]
};
As we can see, there are compatible concepts available, including what looks like a nice evolution of the resolves API which allows function oriented injection which was generally simpler than class based injection in ui-router with AngularJS.
Note, I have not used it in an Angular project.

Categories