I'm new to Vue now working with its router.
I want to navigate to another page and I use the following code:
this.$router.push({path: '/newLocation', params: { foo: "bar"}});
Then I expect it to be on the new Component
this.$route.params
This doesn't work.
I also tried:
this.$router.push({path: '/newLocation'});
this.$router.push({params: { foo: "bar"}});
I've inspected the source code a bit and noticed this property gets overwritten with a new object {}.
I'm wondering is the params use is other than I think?
If not, how to use it?
Since you want to pass params to the component of the respective route you route object's path property should have a dynamic segment denoted by : followed by the name of the key in your params object
so your routes should be
routes: [
{path: '/newLocation/:foo', name: 'newLocation', component: newComponent}
]
Then for programmatically navigating to the component you should do:
this.$router.push({name: 'newLocation', params: { foo: "bar"}});
See that I am using name of the route instead of path as you are passing params by the property params.
if you want to use path then it should be:
this.$router.push({path: '/newLocation/bar'});
by the path approach the params will automatically map to corresponding fields on $route.params.
Now if you console.log(this.$route.params) in your new component you will get the object : {"foo": "bar"}
Try using query instead of params
this.$router.push({path: '/newpath', query : { foo: "bar"}});
And in your component
console.log(this.$route.query.foo)
The easiest way I've found is to use named routes along with the params options. Let's say you have a router file that looks like this:
And you want to reach the "movie" page with some ID. You can use Vue's router link component (or Nuxt's link component) to reach it like this:
Vue:
<router-link :to="{ name: 'movie', params: { id: item.id } }">{{ item.title }}</router-link>
Nuxt:
<nuxt-link :to="{ name: 'movie-id', params: { id: item.id } }">{{ item.title }}</nuxt-link>
Note that the name parameter must match the "name" attribute of the desired route in the router file. And likewise, the parameter name must match.
Nuxt creates the route file for you automatically when you create a
new page. To see what name Nuxt gives its routes, go to the .Nuxt
folder in your project and look for a "router.js" file
Isn't it generally considered an anti pattern to bind the properties to the router?
It's a much more DRY solution to have them bind to the component it's self, which I actually believe the Vue router does. Please see: https://router.vuejs.org/en/essentials/passing-props.html for more info on the best practices here
Can you try accepting the property in the props: [] property of your component? You can see how to do that here: https://v2.vuejs.org/v2/guide/components.html#Props
Please do pop up if you have any questions! Happy to help further.
Related
Current URL is 'https://localhost:3000/lang/countries/states/cities/'
I want to change it to:
https://localhost:3000/lang/compare/?c=1&back=1&query=94&query=911
Basically I want to edit the current URL. I tried using:
this.$router.push({
path:'/lang/compare/?c=1&back=1&query=94&query=911',
});
this.$router.replace({
path:'/lang/compare/?c=1&back=1&query=94&query=911',
});
But this changes the URL to :
https://localhost:3000/lang/countries/states/cities/lang/compare/?c=1&back=1&query=94&query=911',
I have tried using window location href but coz of that state of my variable is lost, hence I need to use VUE router for this. Is their any way to change base URL in VUE routes.
Your method is also right it should work if there is no other issue,
try with
this.$router.push({ path: '/lang/compare', query: { c: 1,back:1,firstquery:94,queryB:991}})
or you can also try with $router name defining a name on router index file
{
path: "/lang/compare",
name: "compare",
component: comparePage,
},
this.$router.push({ name: 'compare', query: { c: 1,back:1,firstquery:94,queryB:991}})
I have a lot of articles in my app, and the URL are written like this in Vue Router: /article/:id.
I have particular articles I want to "pin" and have easier URLs. For example: /pinned-article, which should point to /article/3274 and /other-pinned-article, pointing to /article/68173.
I though about adding this to my routes, but it doesn't work:
{ path: '/article/3274', component: Article, alias: '/pinned-article' }
I thought about something else, involving another component:
{ path: '/pinned-article/:id', component: PinnedArticle }
The component PinnedArticle silently aliasing the correct article with a command like router.alias in the <script> section, but it apparently doesn't exist.
Is there a way to solve this problem? I thought I could use some answers I read here in Stackvoverflow (for examples when it comes to redirect /me to /user/:id, but it doesn't apply.
Thanks in advance :)
addRoute
You can achieve this with Dynamic Routing, which is not the same as dynamic route matching, i.e. route params.
(This solution works in both Vue 3 and Vue 2 with Vue Router >= 3.5.0)
By using the addRoute method of Vue router, you can create routes at runtime. You can either use a redirect or not, depending on whether you want the url bar to read /article/3274 or /pinned.
Redirect
If you want the url to change from /pinned to /article/3274, use redirect:
methods: {
pinRoute() {
this.$router.addRoute({
path: '/pinned',
name: 'pinned',
redirect: { name: 'article', params: { id: 3274 }}
})
}
}
Access the route like:
this.$router.push('/pinned')
The above example assumes you give your Article route a name: 'article' property so you can redirect to it
Alias
You can keep the URL as /pinned using alias. Normally the alias would go on the existing Article route definition, but that doesn't work well with route params. You can use a "reverse alias" with a new route:
methods: {
pinRoute() {
this.$router.addRoute({
path: '/params/3274',
name: 'pinned',
alias: '/pinned',
component: () => import('#/views/Article.vue') // Article component path
})
}
}
Access the route like:
this.$router.push('/pinned')
Notes:
You'll probably want to pass an id argument to the pinRoute methods rather than hardcode them like in the examples above.
A nice thing about addRoute with either method above is if the route already exists, say, from the last time you called the method, it gets overwritten. So you can use the method as many times as you like to keep changing the destination of /pinned. (The docs in both Vue 2 and Vue 3 say the route definition will get overwritten, though Vue 2 router throws a duplicate route warning.)
Of course the pinned route won't automatically persist between app refreshes, so you'll need to save/load the pinned id (i.e. using localStorage, etc.) and run one of these methods on app load if you want that
I have list of users which I output in Home vue component. Every item in the list is coming from vuex and has it's own details. When I click any of this contacts list items vue-router takes me to route /contact/that-item-id for example contact/4536475. Now, when I am on that page for specific contact list item and refresh my browser vue app breaks, in other words I don't have access to that specific item object properties anymore.
Here is the code of my router
export default new Router({
routes: [
{
path: "/",
name: "Home",
component: Home
},
{
path: "/contact/:id",
name: "ContactDetails",
props: true,
component: ContactDetails
I am setting props property to true so I can pass it as params to contact item details component as so:
<router-link
class="view-more-btn"
:to="{ name: 'ContactDetails', params: { id: contact.id }}"
>VIEW DETAILS</router-link>
and at last I am passing that Id to my getters method in vuex to get details for clicked item as this:
export default {
props: ["id"],
computed: {
contact() {
return this.$store.getters.getContactDetails(this.id);
}
}
Where did I go wrong, why I can't refresh my contact item detail page and still preserve state I am using.
I am new to vue so please forgive me if I am not making sence. And ofcourse any help is welcomed, thanks in advance
The problem is probably, that you're referencing a named route and passing in the params by hand. This won't change the actual route displayed in your browsers address bar and only show the root path (/contact/ in your example I presume). Therefore when you refresh the passed in params/props simply don't exist anymore.
What you need to do instead is use a <router-link :to="'/contact/'+contact.id"> or <router-link :to="`/contact/${contact.id}`"">.
This should affect the URL in your browsers address bar to include the /contact/someID123 which will then also make the ID available on refresh.
I am trying to send data from one vue component to another by using props in router. but it is not working. whenever i try to log the props it outputs undefined. code is given below
From where data is sending
Where receiving
in index.js. router setting
None of the code you've posted matches up.
Firstly, the console logging should be just console.log(this.myprops). The point of using props is that you don't need to reference the router itself, e.g. via $router.
Next problem, you're mixing path and params. That isn't allows. See https://router.vuejs.org/guide/essentials/navigation.html. params are for named routes.
I imagine what you're aiming for is something like this:
self.$router.replace({ name: 'DashboardPatient', params: { myprops: authUser.email } })
with router config:
{
path: '/patient',
component: Dash,
children: [
{
path: ':myprops', // <--- Adding myprops to the URL
name: 'DashboardPatient',
component: DashboardPatient,
props: true,
meta: { requiresAuth: true }
}
]
}
Keep in mind that routing is all about building and parsing the URL. So the value of myprops needs to be in the URL somewhere. In my example it comes at the end, so you'll get /patient/user#example.com as the URL. If it weren't in the URL then there'd be no way for the router to populate the prop if the user hit that page directly (or refreshed the page).
To hit the same route using a path instead of a name it'd be something like this:
self.$router.replace({ path: `patient/${encodeURIComponent(authUser.email)}` })
or even just:
self.$router.replace(`patient/${encodeURIComponent(authUser.email)}`)
Personally I'd go with the named route so that the encoding is handled automatically.
If you don't want to put the data in the URL then routing is not the appropriate way to pass it along. You'd need to use an alternative, such as putting it in the Vuex store.
According to official docs
Sometimes it is more convenient to identify a route with a name,
especially when linking to a route or performing navigations.
So, how is this can be more convenient?
<router-link :to="{ name: 'user', params: { id: user.id }}">
{{ user.name }}
</router-link>
vs
<router-link :to="'/user/' + user.id">
{{ User.name }}
</router-link>
I feel like I'm missing something obvious.
I always use named routes.
The advantage is that you can change the path of the route without needing to change the path in every <router-link> or this.$router.push() call.
It's kind of like the reason why, in programming, we avoid magic values and instead use named constants – we can change the value in one place without needing to find-and-replace all occurrences of the value in our code.
Without using named routes, your code becomes tightly bound to the path of each route, you can't change one without needing to change the other. Named routes makes our code independent of the route paths – it'll work whatever the path of the route ends up being.
Another advantage is we can take advantage of param/query inheritance for nested routes – we don't need to reconstruct the full path, instead we can just pass the name of the child route and Vue will construct the full path with any existing params.
Suppose we have the following routes:
{
name: 'user',
path: '/user/:id',
children: [
{
name: 'profile',
path: 'profile'
}
]
}
and the current route path is /user/1. To go to the profile page, we need to do either:
this.$router.push({ name: 'profile' })
or
this.$router.push('/user/' + this.$route.params.id + '/profile')
The former is simpler and less error prone.