Vuejs - How to pass params from child route to parent route? - vue.js

I am a beginner in vuejs.
I have an issue with some practice about vue-router nested route.
Just in case, This is a nested route config.
const router = new Router({
routes: [
{
path: '/dashboard',
name: 'dashboard',
component: Dashboard,
meta: {
requiresAuth: true
},
children: [
{
path: 'overview',
name: 'Overview',
component: Overview,
meta: {
requiresAuth: true
}
}
]
}
]
})
If I want to pass data from a child route (overview) to parent route (dashboard)
How should I handle it ?
I don't want the url have any change (/dashboard/overview), just receive the data params from child route.

You might want to consider using Vuex as a means of sharing state across different components (or maybe not if you're a beginner).
Alternatively you can just emit an event in the child component:
Vue.use(VueRouter);
var Parent = {
template: '<router-view #data="onData"></router-view>',
methods: {
onData(data) {
alert('Got data from child: ' + data);
},
},
};
var Child = {
template: '<div><input v-model="text"><button #click="onClick">Click Me</button></div>',
data() {
return {
text: 'Hello',
};
},
methods: {
onClick() {
this.$emit('data', this.text);
},
},
};
var router = new VueRouter({
routes: [
{
path: '',
component: Parent,
children: [
{
path: '',
component: Child,
},
],
},
],
});
new Vue({
el: '#app',
router,
});
<script src="https://rawgit.com/vuejs/vue/dev/dist/vue.js"></script>
<script src="https://rawgit.com/vuejs/vue-router/dev/dist/vue-router.js"></script>
<div id="app">
<router-view></router-view>
</div>

Related

Component doesn't load while the route changes

I want to create a nested route with its children's route.
Basically what I want is,
https://localhost/contact render the ContactList component.
https://localhost/contact/add render the ContactAdd component.
What I have tried is:
let Layout = {
template: '<div>Layout Page <router-view></router-view></div>'
};
let Home = {
template: '<div>this is the home page. Go to <router-link to="/contact">contact</router-link> </div>'
};
let ContactList = {
template: '<div>this is contact list, click <router-link to="/contact/add">here</router-link> here to add contact</div>'
};
let ContactAdd = {
template: '<div>Contact Add</div>'
}
let router = new VueRouter({
routes: [{
path: '/',
redirect: 'home',
component: Layout,
children: [{
path: 'home',
component: Home
},
{
path: 'contact',
component: ContactList,
children: [{
path: 'add',
component: ContactAdd
}]
},
]
}]
});
new Vue({
el: '#app',
components: {
'App': {
template: '<div><router-view></router-view></div>'
},
},
router
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/vue-router#3.0.1/dist/vue-router.js"></script>
<section id="app">
<app></app>
</section>
Here, the problem is when I change the route from /client to /client/add, the view doesn't render. What is the problem with the nested children's route here? How to solve this issue?
I check this documentation https://router.vuejs.org/guide/essentials/nested-routes.html, but It didn't help in this case.
You need to add one <router-view> in the template of <ContactList> to load its children route.
Or if you'd like to display ContactAdd in Layout, moves ContactAdd to direct child of path=/.
let Layout = {
template: '<div>Layout Page <router-view></router-view></div>'
};
let Home = {
template: '<div>this is the home page. Go to <router-link to="/contact">contact</router-link> </div>'
};
let ContactList = {
// add <router-view> in order to load children route of path='/contact'
template: '<div>this is contact list, click <router-link to="/contact/add">Add Contact In sub Router-View</router-link> here to add contact<p><router-view></router-view></p> Or Click <router-link to="/addcontact">Add Contact In Current Router-View</router-link></div>'
};
let ContactAdd = {
template: '<div>Contact Add</div>'
}
let router = new VueRouter({
routes: [{
path: '/',
redirect: 'home',
component: Layout,
children: [{
path: 'home',
component: Home
},
{
path: 'contact',
component: ContactList,
children: [{
path: 'add',
component: ContactAdd
}]
},
{
path: 'addcontact', // or move ContactAdd as direct child route of path=`/`
component: ContactAdd,
}
]
}]
});
new Vue({
el: '#app',
components: {
'App': {
template: '<div><router-view></router-view></div>'
},
},
router
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/vue-router#3.0.1/dist/vue-router.js"></script>
<section id="app">
<app></app>
</section>

Vue-router - using two different paths, children don't load from second path

children in route, name: matchDayRegistrationResult don't get loaded, when I move them to name: matchDays they load fine. But I need a different top level component, HomepageLayoutRatio5050 -> HomepageLayoutRatio2575
I could not find a working example in the Vue docs
const router = new VueRouter({
mode: 'history',
routes:
[
{
path: '/:lang',
name: 'matchDays',
component: HomepageLayoutRatio5050,
children: [
{
path: '/:lang',
components: {
descriptionBlock: MatchDaysDescription,
mainBlock: MatchDaysTable,
notesBlock: MatchDaysNotes
}
},{
path: '/:lang/matchday/registration/:id',
name: 'matchDayRegistration',
components: {
descriptionBlock: RegistrationFormDescription,
mainBlock: RegistrationForm
}
}]
},
{
path: '/:lang/matchday/registration/result/:id',
name: 'matchDayRegistrationResult',
component: HomepageLayoutRatio2575,
children: [
{
path: '/:lang/matchday/registration/result/:id',
components: {
descriptionBlock: RegistrationResultDescription,
mainBlock: RegistrationResultDetails,
notesBlock: RegistrationResultNotes
}
}]
}
]
});
HomepageLayoutRatio2575 does load,
but children: descriptionBlock: RegistrationResultDescription
mainBlock: RegistrationResultDetails notesBlock:
RegistrationResultNotes Don't.
Found THE solution, as the localisation part, /:lang was the culprit, blocking the second route (...logic) I reordered the routing schema.
To the benefit of people, having hard times, looking for complex vue router-view solutions, localisation aware, here's the solution :-)
const router = new VueRouter({
mode: 'history',
routes:
[
{
path: '/:lang',
component: HomeSweetHome,
children: [{
path: '/:lang',
name: 'matchDays',
components: {
homepageSidebarLayoutRatio: HomepageSidebarLayoutRatio5050,
homepageMainLayoutRatio: HomepageMainLayoutRatio5050,
footer: FooterGray
},
children: [
{
path: '/:lang',
components: {
descriptionBlock: MatchDaysDescription,
mainBlock: MatchDaysTable,
notesBlock: MatchDaysNotes
}
},{
path: '/:lang/matchday/registration/:id',
name: 'matchDayRegistration',
components: {
descriptionBlock: RegistrationFormDescription,
mainBlock: RegistrationForm
}
}
]
},{
path: '/:lang/matchday/registration/result/:id',
components: {
homepageSidebarLayoutRatio: HomepageSidebarLayoutRatio2575,
homepageMainLayoutRatio: HomepageMainLayoutRatio2575,
footerNotesBlock: RegistrationResultFooterNotes,
footer: FooterBlack,
},
children:[{
path: '/:lang/matchday/registration/result/:id',
name: 'matchDayRegistrationResult',
components: {
descriptionBlock: RegistrationResultDescription,
mainBlock: RegistrationResultDetails
}
}]
}]
}
]
});

VueJS: router.resolve issue

A warning is shown in the console:
the id param was not provided.
The docs mention that the current route will be used:
current is the current Route by default (most of the time you don't
need to change this)
html code:
<div id="app">
<router-link to="/5">/5</router-link>
<button #click="onClick">Resolve</button>
</div>
js code:
new Vue({
el: '#app',
router: new VueRouter({
routes: [
{
name: 'foo',
path: '/:id',
component: {
template: '<div>Foo <router-view/></div>',
},
children: [
{
name: 'bar',
path: 'bar',
component: {
template: '<div>Bar</div>'
}
}
]
},
],
}),
methods: {
onClick() {
console.log('Omitting current');
this.$router.resolve({ name: 'bar' });
console.log('Including current');
this.$router.resolve({ name: 'bar' }, this.$route);
}
}
});
I know this is overdue, but I'll share what I found.
When you call $router.resolve(), it uses vue-router/src/util/location.js's normalizeLocation() to get the Location object.
And you can see there that the current? option is only used to resolve relative paths.
The only case where current.params is included in the new Location is when the given RawLocation is relative, and includes params itself.

Vue tree navigation (pluggin) how to map routes

I have used vue-tree-navigation for implement this Tree navigation menu .
When I hit a menu item (eg :- Create item) it should route to the create item component.
But it's only print the name of the route in the navigation bar and doesn't route to any where.
http://localhost:8080/inside#item
how do I fixed this problem?
this is my routes.js file
const routes = [
{ path: "/", component: welcome },
{
path: "/inside",
component: inside,
name: inside,
children: [
{ path: "/category", component: category, name: category },
{ path: "/sub-category", component: subCategory, name: subCategory },
{ path: "/item", component: item, name: item }
]
}
];
This is my component
<template>
<div class="inside">
<div class="sideBar"><vue-tree-navigation :items="items" /></div>
<div class="content"><router-view></router-view></div>
</div>
</template>
<script>
export default {
data() {
return {
items: [
{ name: 'Item Master', route: 'inside', children: [ // /about
{ name: 'Create item category', element: 'category', },
{ name: 'Create item sub category', element: 'sub-category', },
{ name: 'Create item', element: 'item', },
]},
],
};
}
};
</script>
Try to change a bit of things in the router file, it works well for me:
The components starts in Uppercase (just a convention)
The name with ''
Delete the / in the path
Like this:
path: "inside",
component: Inside,
name: "inside",
children: [
{ path: "category", component: Category, name: 'category' },
{ path: "sub-category", component: SubCategory, name: 'subCategory' },
{ path: "item", component: Item, name: 'item' }
]
And the most important, load (if you are not doing it already) the VueRouter with:
var router = new VueRouter({
const routes = [
...
]
});
Hope it helps!

Passing props to nested route

I have the following routes in my VueJS app:
const routes = [
{
path: '/',
component: PlacesList
},
{
name: 'place',
path: '/places/:name',
component: CurrentWeather,
children: [
{
name: 'alerts',
path: 'alerts',
component: ForecastAlerts
},
{
name: 'forecast',
path: 'forecast',
component: ForecastTimeline
}
]
}
];
ForecastTimeline receives props passed from CurrentWeather:
export default {
name: 'ForecastTimeline',
props: ['forecastData'],
components: {
ForecastDay
}
}
When I navigate to /places/:name/forecast from /places/:name everything works well. However, when I try to reach /places/:name/forecast directly I get a Cannot read property 'summary' of undefined error. This occurs because forecastData is fetched asynchronously within the CurrentWeather component. What is the proper way to handle asynchronous properties passed to a nested route?
Have you tried not displaying the subroutes components while fetching the data ?
Something like :
export default {
name: 'CurrentWeather',
data(){
return {
loading: true
}
},
created(){
this.fetchForecastData().then(() => {
this.loading = false;
});
},
methods: {
fetchForecastData() {
return fetch('http://..');
}
}
}
In CurrentWeather template :
<router-view v-if="!loading"></router-view>