How to pass props to named views through <router-link /> in vuejs? - vue.js

I’m new to VueJS and front end development.
I’m looking to pass a props (in this case, my club’s id) to my component/view.
It was initially working with <router-link :to="{ name: 'club', params: {id: club.id } }">.
My component call a props “id”, and my view, named club has the parameter props:true;
Fast forward a little later, i had to add named view. (I only added one for now - but i’ll have a view content and one nav).
mode: 'history',
base: process.env.BASE_URL,
linkExactActiveClass: 'is-active',
routes: [
{
path: '/',
name: 'clubs',
components: {
content: Clubs
}
},
{
path: '/club/:id',
name: 'club',
props: true,
components: {
content: Club
}
}
]
})
And this broke everything.
In the Vue extension, i can see that my send is sending my props as a param (see attachement 1), but once on the view, the id is undefined (see attachment 2).
Am i missing anything?
Attachement 1
Attachement 2

You'd need to set a props value for each named view in that case. e.g.
components: {
content: Club
},
props: {
content: true
}
I can't find a decent explanation of this in the documentation but it does feature in an example here:
https://router.vuejs.org/guide/essentials/passing-props.html
Note the following comment lurking in the code example:
// for routes with named views, you have to define the `props` option for each named view:

Related

Sending variables from one view to another view and url in vue

What I want is when I click an image, it redirects to a URL (another view) which is made by the something/image_name. I am making the project in vue.js. I am thinking of doing this by using props (passing all the variables needed from the first view to the next view). But the data is not displayed in the 2nd view. Also, I want to know how can I make the URL like something/image_name. I am using it by hardcoding the URL.
routes.js
const router = new Router({
mode: "foo",
base: "foobar",
routes: [
{
path: "/event/:title",
name: "event",
component: event,
props: true,
}
where title is the variable (event.title to be more precise) I want to pass from other view. I also want to get title in URL also.
view 1
<template>
<div src="image_location" :to="/event/{{event.title}}"></div>
</template>
<script>
export default {
name: "event",
components: {
Event
},
data: function initData() {
return {
event: {},
};
},
};
</script>
view 2 (Event.vue) (its URL should be foobar/event/{{ title }})
props: {
event: Object,
}
I tried router-link also but lack of its documentation restricts me from using it efficiently.
You can add an #click event to the image and programmatically move the user to the new URL when they click on the image. Something like:
<imge src="..." #click="$router.push(`/event/${event.title}`)" />

What does the name option in routes:[] actually refer to (Vue.js CLI3)?

Ìm new to vue.js and I#m practicing routing right now.
My router.js looks like this:
import Vue from 'vue'
import Router from 'vue-router'
import Home from './views/Home.vue'
Vue.use(Router)
export default new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/',
name: 'home',
component: Home
},
{
path: '/about',
name: 'about',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ './views/About.vue')
},
{
path: '/myView',
name: 'myView',
component: () => import('./views/myView.vue')
}
]
})
Now I thought the name option referred to the name I've given the "component".
For example, I tried out the following with "myView" view:
<template>
<div>
<myWorld placeholder="tester"/>
</div>
</template>
<script>
import myWorld from '#/components/myWorld.vue'
export default {
name: 'sklfdjns',
components: {
myWorld
}
}
</script>
As you can see, the name is just gibberish. If the name option in the router really referenced this name in the component, Id expect it to fail.
But it doesnt. Everything works just fine.
Then I tried out changing the name in the router option, but nothing changed as well.
So what does this name option actually do?
Unfortunately, the official Documentation wasnt helpful for me either..
https://router.vuejs.org/guide/essentials/named-routes.html
As mentioned in docs router names are different than component names
purpose of named routes is to navigate without giving full URL i.e just by giving name and it's not reference to component name it's just name of your route
router.push({ name: 'user', params: { userId: 123 }})
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
both will navigate to user route which is '/user/:userId'
As stated in the docs you posted, the name can be added for convenience. This can be helpful for longer paths or for iterating your routes into a menu for example.
To call such a route you then can use the name instead:
<router-link :to="{ name: 'home' }">home</router-link>
Another convenience example where i used the names before is iterating it into a menu with $route.name, you want readable names there.
Adding to Answer 1... the name mostly used when you want to push users from one page to another after something has happened
this.$router.push({name:'details'})
if the details name does not exist, you get an error
and also when you are also specific to a particular route, according to the first answer
the name in the component specifics name of that component.
This is useful in vue devtool for debugging, or when you want to render a component recursively, you have to set a name for the component. For example, you want to render component comment inside the template of a comment (to display sub-comment).
The name in router is name of that route.
For example:
you have a route like this
{
path: '/',
component: Home
},
when you want to go to the root page, you do some thing like this, right?
this.$router.push('/')
What if I want to change the root path to /admin?
I will have to find all this code this.$router.push('/') and replace the path? No way!
Instead, I will specific a route name name: 'root', and navigate through routes by name.
{
path: '/',
name: 'root',
component: Home
}
this.$router.push({ name: 'root' });
Once I want to change the route path, I just change the path in router.js
The name in component property and the one from route has no relation.

Dynamic Vue Router

I am researching whether a vue router is the best approach for the following scenario:
I have a page containing 'n' number of divs. Each of the divs have different content inside them. When a user clicks on a button in the div, I would like the div to open in a separate browser window (including its contents).
Can a route name/component be created on the fly to route to? Since I have 'n' number of divs, that are created dynamically, I cannot hard-code name/components for each one
<router-link :to="{ name: 'fooRoute'}" target="_blank">
Link Text
</router-link>
I want to avoid the same component instance being used (via route with params) since I may want multiple divs to be open at the same time (each one in their own browser window)
If the link is opening in a separate window, it makes no sense to use a <router-link> component as the application will load from scratch in any case. You can use an anchor element instead and generate the href property dynamically for each div.
To answer your questions:
A route name cannot be created dynamically since all routes must be defined at the beginning, when the app (along with router) is being initialized. That said, you can have a dynamic route and then dynamically generate different paths that will be matched by that route.
There is no way for the same component instance to be reused if it's running in a separate browser window/tab.
It is possible to create dynamic router name.
profileList.vue
<template>
<main>
<b-container>
<b-card
v-for="username in ['a', 'b']"
:key="username"
>
<b-link :to="{ name: profileType + 'Profile', params: { [profileType + 'name']: username }}">Details</b-link>
</b-container>
</main>
</template>
<script>
export default {
name: 'profileList',
data () {
return {
profileType: ''
}
},
watch: {
// Call again the method if the route changes.
'$route': function () {
this.whatPageLoaded()
}
},
created () {
this.whatPageLoaded()
},
methods: {
whatPageLoaded () {
this.profileType = this.$route.path // /user or /place
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style>
</style>
b-container, b-card, b-link are taken from bootstrap-vue, so you can freely change it.
router.js
const router = new Router({
mode: 'hash',
base: process.env.BASE_URL,
linkExactActiveClass: 'active',
routes: [
// USERS
{
path: '/user/:username',
name: userProfile,
component: userProfile
},
{
path: '/user',
name: 'userList',
component: profileList
},
// PLACES
{
path: '/place/:placename',
name: placeProfile,
component: placeProfile
},
{
path: '/place',
name: 'placeList',
component: ProfileList
}
]
})

VueJs use props that comes from <router-link>

i have a navbar and there is a text field in that the user can search for posts by tags. If the user enters 1-3 tags, the written tags will be stored in a tags array.
My router-link in the navbar component looks like this: (only relevant part)
<router-link :to="{name:'posts', props:{searchTags: tags}}">
<button type="button" v-if="this.tags.length > 0"
class="...">Search
</button>
</router-link>
in my routes.js is my posts route (important snippet of my routes.js)
routes: [
{
path: "/posts",
component: posts,
name: 'posts'
},
]
The navbar should send the tags array to the posts component. Unfortunately I can't do it.
The posts component, sends a post request to an API that gets the latest posts. But I want that when tags are passed, not the newest posts are fetched, only posts with certain tags. But first I have to get the tags somehow.
I tried to get them with "this.$props.searchTags" and other things. Unfortunately the result is always "undefined".
export default {
name: "posts",
props: {
searchTags: Array,
required: false
},
data: function () {
return {
apiUrl: '/getPosts',
....
tags: [this.searchTags],
}
},
methods: {
getPosts: function (url) {
this.$http.get(url).then(function (data) {
// blabla
});
},
getPostsByTags: function() {
//
},
},
created() {
if(this.$props.searchTags == null)
this.getPosts(this.apiUrl);
else
this.getPostsByTags(bla);
},
}
Router link to property accepts string or Location as a value. Location object does not have props property.
Instead, it is possible to use params to send data to route component:
<router-link
:to="{ name: 'posts', params: { searchTags: tags } }"
>
...
</router-link>
This way searchTags with value of assigned tags will be accessible via this.$route.params.searchTags inside destination component.
So created hook of example above should be updated to:
created () {
if (!this.$route.params.searchTags) {
this.getPosts(this.apiUrl);
} else {
this.getPostsByTags(bla);
}
},
Try to add props: true in your route definition
routes: [
{
path: "/posts",
component: posts,
name: 'posts',
props: true
},
]

Navigating to Child Components with Vue.js

I have an app built with Vue.js. In this app, I'm using the Vue Router. I successfully have top-level routes working. However, I'm unable to get child routes to work. My code seems to ignore any routes defined within the children property of a route. I've setup the problem in this fiddle. The relevant code looks like this:
const CustomerMenu = { template: '<div><br />please choose: <router-link to="/customers/list">list</router-link> <router-link to="/customers/stats">stats</router-link></div>' }
const CustomerList = { template: '<div>A list of customers here</div>' };
const CustomerStats = { template: '<div>Customer statistics</div>' };
const Suppliers = { template: '<div>Suppliers</div>' }
const router = new VueRouter({
mode: 'history',
routes: [
{ path: '/customers', component: CustomerMenu, children: [
{ path: 'list', component: CustomerList },
{ path: 'stats', component: CustomerStats }
]},
{ path: '/suppliers', component: Suppliers }
]
})
new Vue({
router,
el: '#app',
data: {}
});
How do I show the content associated with a route defined in the children property of a route. In other words, how do I get the "list" or "stats" components to appear when a user selects there respective links?
Thank you!
You were missing <router-view/> inside your CustomerMenu component.
http://jsfiddle.net/sn5vu6ek/
Remember - every component which has children routes has to have to be able to display children components.
If you just want to have some part of path common between components, you can either create parent with just <router-view/> inside, or specify full path for multiple components.