Vue.js passing array from one page to another - javascript

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

Related

How to use a component depending on the route

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>

VueJS pushing route with params shows old params in browser

Scenario
I've a app where I use vue.js 2.6 and vue-router 3.0
in there I've links to detail pages like this
<div v-for="item in items">
<router-link :to="{name: 'details', params: {key: item.shortKey}}">
</div>
what works
Now in the target view the parameter always has the correct value
Also when I first time click a link then I see the correct shortkey in the browser.
Not working
Now when I click another itemm I still see in the browser url the key of the item that was clicked first in the browser . Eventhough inside the code the route.params do have the correct value.
Both the View browser tools and the code itself have the correct value.
What am I missing?
Also using router.push has the same result. Changing from history to hash mode also doesn't change the behavior
Shortened Router config
const routes = new Router({
mode: 'history',
routes: [{
component: layout,
path: '/',
children: [
{
path: '/',
name: 'home',
component: Home,
meta:{display:"home"}
},
{
path:'list',
name:'list',
component: listItemsComponent,
},
{
path: 'details/:key',
name: 'details',
component: detailComponent
},
]
}]
});
Try adding a unique key to each element in v-for like below -
<div v-for="item in items" :key="item.id">
<router-link :to="{name: 'details', params: {key: item.shortKey}}">
</div>
As per vue js docs,
To give Vue a hint so that it can track each node’s identity, and thus
reuse and reorder existing elements, you need to provide a unique key
attribute for each item.
You can try to add '/' in your path : path: '/details/:key'

Refresh data on vue

This may have been asked but I have not be able to find a solution. I have a index page that loads a left nav vue. On that view is a typeahead input with names. When a name is selected a function is called and and a unique value is passed as the pmid_list
this.$router.push({ name: 'About', params: { pmid_list: item.PMID_Include } }
This works fine the first time because the About vue is loaded and the function is called with the pmid_list value. Every name works fine if I refresh the page between calls. If I don't refresh the correct pmid_list (parameter) is sent to the router but the router decides to send the old one if the vue component has not changed.
From what I have read it is a router issue but I can't figure out how to force it to refresh.
export default new Router({
mode: 'history',
routes: [
{
path: '/about/:pmid_list',
name: 'About',
component: About,
props: {default: true}
}
The About component is being cached.
One thing to note when using routes with params is that when the user navigates from /user/foo to /user/bar, the same component instance will be reused. Since both routes render the same component, this is more efficient than destroying the old instance and then creating a new one. However, this also means that the lifecycle hooks of the component will not be called.
Dynamic Route Matching
As shown in the documentation, you should use a watcher to react to parameter changes:
watch: {
'$route' (to, from) {
// react to route changes...
}
}
You can try to watch your route changes.
watch:{
'$route.params.pmid_list': function (pmid_list) {
//your logic here
}
},

Pass dynamic data to router-link.

I'm trying to pass a dynamic path to vue-router but I can't seem to give it the correct syntax. Here is what I'm trying.
<li v-on:click="$emit('closeDropdown')"><router-link to="item.route" id="button">{{ item.title }}</router-link></li>
Is just wrapping it in quotes not enough because this is what I see when I inspect the elements: href="#/item.route" for all items.
PARENT COMPONENT
<UserDropdownList v-for="item in userDropdownItems" v-bind:item="item"></UserDropdownList>
data: function () {
return {
userDropdownItems: [
{ title: 'Profile', route: "/profile" },
{ title: 'Users', route: "/users" }
]
}
}
How can I access the route property for the Router-link to attribute?
Using Dynamic Route Parameters
If you take a look at the vue-router documentation, what you're describing sounds very much like a job for dynamic route parameters:
const router = new VueRouter({
routes: [
// dynamic segments start with a colon
{ path: '/user/:id', component: User, name: 'user' }
]
});
Then, to generate a link via <router-link> for said route, you'd do the following:
<!-- named route -->
<router-link :to="{ name: 'user', params: { id: 123 }}">User</router-link>
Directly using variable with router-link
To use variables in a router link, all you have to do is this:
<router-link :to="item.route" id="button">{{ item.title }}</router-link>
Adding a colon (:) before the to attribute tells Vue that you're about to use some javascript in there.
Using query parameters
Instead of using dynamic route parameters OR js variables, you could use the query option instead:
<!-- with query, resulting in `/register?plan=private` -->
<router-link :to="{ path: 'register', query: { plan: 'private' }}">Register</router-link>
Hope this helps! I've attached all the documentation sources where I found this. I highly recommend giving it a solid look through, as it is one of the most well-written documentation sites I've ever come across.

Rendering a child route in the parent in Angular 4

With Angular 2, I could make a child route render "over" its parent by defining an empty path and creating an essentially empty base component. I am trying to accomplish something similar with the new Angular router (version 4.3.1), but have hit a roadblock.
To reproduce my problem, here's a Plunker. The routes are defined as:
[{
path: '',
redirectTo: "/master",
pathMatch: "full"
}, {
path: 'master',
component: MasterComponent,
children: [{
path: 'detail/:value',
component: DetailComponent,
children: [{
path: 'subdetail',
component: SubDetailComponent
}]
}]
}]
When I navigate to a detail page, the master page is still visible because I have added a <router-outlet></router-outlet> to MasterComponent. What I need is to replace the master view with the detail. I can accomplish this by making detail/:value a sibling of master rather than a child, but this isn't logically correct in my application and breaks my breadcrumbs.
Is there any proper way to handle this kind of pattern, or will I have to pick a workaround, such as showing and hiding the intended route or manually specifying a dedicated "main" outlet for every link?
The only existing solution that comes close is to define a dummy parent component, but this only works one-level down. If my detail page has another sub-detail page that should also replace master, it gets very messy.
Is there any route-level flag I can set or design pattern to implement to elegantly accomplish this? I am an Angular 2 beginner, but I feel as though something like this should be simple.
First, there is no "new" router in 4.3.1. It's the same router from 2.x.
Second, there were a few changes I needed to make to your plunker to make it work appropriately. The key change was this in the master.component.ts:
<a [routerLink]="['/detail', 5]">
I added a slash. Without the slash it was looking for a route named master/detail/5
The route definition is now flat, so everything will appear "under" your main header.
export const routes: Routes = [
{
path: '',
redirectTo: 'master',
pathMatch: 'full'
},
{
path: 'master',
component: MasterComponent
},
{
path: 'detail/:value',
component: DetailComponent
}
];
The updated plunker is here: https://plnkr.co/edit/EHehUR6qSi248vQPDntt?p=preview

Categories