I know this cannot be this difficult, all I want to do is detect the query parameter and pass it to my component. What do I have to do to access router from a component in Vue?
<router-link :to="{ path: '/', query: { myQuery: /*query parameter here/* } }" >Go There</router-link>
No matter what I do I can't figure it out. I've tried everything I can find online, and for some reason in Vue "this" doesn't exist, and I'm literally ready to give up and go back to Angular.
Seriously, I can't even access it inside the tag, and importing the actual router from the routing file does nothing.
How do I make this happen? I feel like it shouldn't be this complicated just to get query parameters from the url in ANY framework. I've been reading manuals all day, can somebody please just help me out here?
The current route's query is in this.$route.query and you can pass that entire query object on to another route if you want to preserve it in the destination:
<router-link
:to="{ path: '/', query: $route.query }"
>
Go There
</router-link>
If you only want to pass a specific query param:
<router-link
:to="{ path: '/', query: { myQuery: $route.query.myQuery }}"
>
Go There
</router-link>
Related
hello guys i'm new to vue js and i'm trying to pass paramenters to a specific router this should happen when i click on a card research and then it will redirect to the research details component called actions-log but when i call this router via
this.$router.push({ name: "actions-log", params: { Id: "3" } })
it gives me an error in the console says:
Uncaught (in promise) Error: No match for {"name":"3","params":{}}
so can any one help me with that error please......
You can use path
const routeId = 3
this.$router.push({ path: `/actions-log/${routeId}` })
i figured out what's happening i have a component called pageTitle this component is included by every other component i use it to make the breadcrumb using the:
this.$route.fullPath
then spliting it and looping the values with :
<li><router-link></router-link></li>
to make the breadcrumbs links but the fullPath prop of the vue router it returns the params too so through the loop in:
<router-link :to="{ name: {path} }">{{ path }}</router-link>
vue checks if the router is exists with the given name, for example when i put /actions-log/3 as params int the url it will be set in the :to attribute becuase of this behavios it's launch that exception;
so i think i solved the problems in the following computed fuction :
i don't know if someone has a better idea to create a breadCrumbs in vue...
anyway thank you so much for helping me to resolve this problem.
Please may someone help me with a params/named route question.
I'm trying to achieve an optional named route change at the first level while maintaining nested structure. Is there a way to achieve this using named routes?
For example imagine use case, either:
/europe/train
or
/car/europe/spain
I would have a new named route going to train instead of car and the behaviour to link to the full path of:
/train/europe/spain
Currently this takes you to the base route with the first level /train removing nested routes, you then need to reselect Europe and Spain.
This is the current setup I'm trying to achieve this:
path: '/:transportSlug?',
name: 'Transport',
...
children: [
{
path: ':regionSlug',
name: 'Region',
...
children: [
{
path: ':countrySlug',
name: 'Country',
...
<router-link :to="{
name: 'Transport',
params: {
transportSlug: filter.slug,
regionSlug: region.slug,
countrySlug: country.slug
}
}">
This is passing in 3 params when navigating to a new base route and all 3 are being correctly passed. I can output them in the view which makes me think it may be a technical limitation/misunderstanding somewhere.
I'm aware of path routing and creating the full path with a computed properly.
Example here
Thank you.
With help from Posva from Vue I was able to solve this.
My approach and understanding of how Vue Router worked was slightly incorrect by thinking that you needed to reference the named route in a nested tree that you wanted to update.
To update the Transport type in /euope/spain I would need to instead reference the Country named route and update the param for the transport.
<router-link :to="{
name: 'Country',
params: {
transportSlug: filter.slug,
}
}">
This maintains the correct URL while updating the Transport type.
Hope this may be of some help to someone.
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'
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.
I found that transition is not firing on dynamic route with parameters. For exemple with the code below, when I am in /chapter/1 and I go to /chapter/2 there is no transition. But when I am in /chapter/1 and I go to /profile/1 there is one !
main.js file
require('normalize.css')
import Vue from 'vue'
import VueRouter from 'vue-router'
import App from './App'
import Panel from './components/Panel'
import Profile from './components/Profile'
window.bus = new Vue()
Vue.use(VueRouter)
const router = new VueRouter({
routes: [
{ path: '/', redirect: '/chapter/1' },
{ name:'chapter', path: '/chapter/:id', component: Panel},
{ name:'profile', path: '/profile/:id', component: Profile}
]
})
new Vue({
router,
el: '#app',
render: h => h(App)
})
App.vue template
<template>
<div id="app">
<transition name="fade" mode="out-in">
<router-view></router-view>
</transition>
<div class="controls">
<router-link :to="{ name: 'chapter', params: { id: Math.max(1, parseInt($route.params.id) - 1) }}">
Prev
</router-link>
<router-link :to="{ name: 'chapter', params: { id: parseInt($route.params.id) + 1 }}">
Next
</router-link>
</div>
</div>
</template>
Maybe is due to the fact that vue-router doesn't destroy the parent component ? I didn't found a way to run the transition from the code. I tried this configuration on vue-router example pack and the behavior is the same.
quote from the doc
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.
To react to params changes in the same component, you can simply watch the $route object
Should I post an issue ?
Thanks for your help !
Can you check this working example: https://jsfiddle.net/mani04/dLnz4rbL/
I attempted to use the method described under Transitioning Between Elements in the docs.
In my fiddle example, which mostly uses the code from your question description, I used a transition wrapper within component, as shown below:
<transition name="fade" mode="out-in">
<div class="page-contents" :key="$route.params.id">
This is my chapter component. Page: {{parseInt($route.params.id)}}
</div>
</transition>
The document specifies that we need to provide a key to make them distinct elements for Vue.js. So I added your chapter ID as key.
I don't know if this is a hack or a proper solution, I moved from Angular2 to Vue only 2 weeks ago. But till someone gives you a better solution, you may use this method to get your transitions for dynamic routes.
Regarding posting this as an issue in github page of vue-router, I am not sure if this qualifies to be addressed / fixed, but you may definitely bring it to their notice. Fix may involve not reusing components, which is also not ideal. So it is a tough call for them. But the discussion should definitely be interesting! Please post back the issue link here if you decide to create one :-)
Came here with the same problem and #Mani's answer works fine.
But I don't really like the idea of using two <transition>s.
So I tried putting the key in <router-view> instead. And it works!
Working example: https://codepen.io/widyakumara/details/owVYrW/
Not sure if this the proper vue-way of doing things, I'm kinda new using vue.
PS. I'm using Vue 2.4.1 & Vue Router 2.7.0