Reputation: 1391
I am implementing a players module. In here , there are 3 routing cards in initial page. Each card is routing to next page which is having multiple routing cards of their respective parent card.
Example
1. 1st level Card( Player Name) -- > 2nd level Cards(Players info, Player Statistics, Records) --> upto 3rd level routing
2. 1st level Card(Grounds) -- > 2nd level Cards(Grounds info, Match played, Records) --> upto 3rd level routing
3. 1st level Card(Match Information) -- > 2nd level Cards(Match info, match history, community resources) --> upto 3rd level routing
Now, i have created that many components with respective routes. But, i want to create one component to route all different routes based on condition( $route.path)
Now, here is my routes.js
{
name: 'Players',
path: '/players',
component: PageLayout,
meta: {
topNavigation: true
},
redirect: { path: '/players/entry' },
children: [
{
name: 'PlayersEntryPage',
path: 'entry',
component: PlayersEntryPage
},
{
name: 'PlayersName',
path: 'name',
component: PlayersName
},
{
name: 'Grounds',
path: 'grounds',
component: Grounds
},
{
name: 'MatchInformation',
path: 'info',
component: MatchInformation
}
]
}
Here is the first home page and then 1st level subsequent card components for routing
PlayersEntryPage
<template>
<vu-page background="gray">
<vu-container>
<vu-row-control class="mt-3">
<vu-box-control :list="cardLists" @click="cardAction"></vu-box-control>
</vu-row-control>
</vu-container>
</vu-page>
</template>
<script>
export default {
data() {
return {
cardLists: [
{ heading: ‘PlName', content:’Players Name and information',to:'/players/name'},
{ heading: ‘Grnd', content: ‘Ground Information', to:'/players/grounds' },
{ heading: ‘Infos', content: ‘Match Informations', to:'/players/info' }
]
};
},
methods: {
cardAction(value) {
if(value) {
this.$router.push(value.to);
}
}
}
};
</script>
1st level component (PlayersName) -> 2nd level component cards
<template>
<vu-page background="gray">
<vu-container>
<vu-row-control class="mt-3">
<vu-box-control :list="cardLists" @click="cardAction"></vu-box-control>
</vu-row-control>
</vu-container>
</vu-page>
</template>
<script>
export default {
data() {
return {
cardLists: [
{ heading: ‘Players Personal Info', to:’/players/name/pinfo'},
{ heading: ‘Players Statistics', to:'/players/name/statistics' },
{ heading: ‘Players Records',to:’/players/name/records' }
]
};
},
methods: {
cardAction(value) {
if(value) {
this.$router.push(value.to);
}
}
}
};
</script>
Box-control code snippet
<template>
<div class="box-wrapper">
<div v-for="(items, i) in boxes" :key="'box-row-' + i" class="box-container">
<vu-button-control
v-for="item in items"
:key="item.heading"
plain
class="box"
:to="item.to"
@click="click($event, item)"
>
<vu-row-control>
<vu-column-control cols="10">
<h1 class="label">{{ item.heading }}</h1>
<p class="body_content">{{ item.content }}</p>
</vu-column-control>
<vu-column-control cols="2">
<vu-button-control @click.stop=“addFavouriteClick(item)">
</vu-button-control>
</vu-column-control>
</vu-row-control>
</vu-button-control>
</div>
</div>
</template>
All other routing cards are following exactly same structure just one difference is the passed data. So, that's why i want one single component and based on $route path i want to change the data part.
I am thinking to use switch case approach but not able to do that conditional routing part.
Upvotes: 0
Views: 879
Reputation: 8329
Sorry, but I'm not sure I understood your problem fully - but I try to give a solution to what I understood:
To achieve that I'd extend the router
to pass subroutes
props to a general component:
const PlayersInfo = {
template: `
<div>Players info component</div>
`
}
const PlayerStatistics = {
template: `
<div>Player statistics component</div>
`
}
const PlayerRecords = {
template: `
<div>Player records component</div>
`
}
const GroundsInfo = {
template: `
<div>Grounds info component</div>
`
}
const MatchPlayed = {
template: `
<div>Match played component</div>
`
}
const GroundsRecords = {
template: `
<div>Grounds records component</div>
`
}
const MatchInfo = {
template: `
<div>Match info component</div>
`
}
const MatchHistory = {
template: `
<div>Match history component</div>
`
}
const CommunityResources = {
template: `
<div>Community resources component</div>
`
}
// RoutingControl can be called inside itself
const RoutingControl = {
props: ["subroutes"],
template: `
<div>
<router-link
v-for="subroute in subroutes"
:key="subroute"
:to="{ name: subroute }"
class="link"
>
{{ subroute }}
</router-link><br />
<router-view />
</div>
`
}
const routes = [{
name: 'Root',
path: '/',
redirect: {
path: '/players/entry',
},
},
{
name: 'Players',
path: '/players',
component: RoutingControl,
meta: {
topNavigation: true
},
redirect: {
path: '/players/entry'
},
props: (route) => ({
subroutes: getRouteNames("Players")
}),
children: [{
name: 'PlayersEntryPage',
path: 'entry',
component: RoutingControl,
props: (route) => ({
subroutes: getRouteNames("PlayersEntryPage"),
}),
children: [{
name: 'PlayersName',
path: 'name',
component: RoutingControl,
props: (route) => ({
subroutes: getRouteNames("PlayersName"),
}),
children: [{
name: 'Players info',
path: 'players-info',
component: PlayersInfo,
}, {
name: 'Player Statistics',
path: 'player-statistics',
component: PlayerStatistics,
}, {
name: 'Player records',
path: 'player-records',
component: PlayerRecords,
}],
},
{
name: 'Grounds',
path: 'grounds',
component: RoutingControl,
props: (route) => ({
subroutes: getRouteNames("Grounds"),
}),
children: [{
name: 'Grounds info',
path: 'grounds-info',
component: GroundsInfo,
}, {
name: 'Match played',
path: 'match-played',
component: MatchPlayed,
}, {
name: 'Grounds records',
path: 'grounds-records',
component: GroundsRecords,
}],
},
{
name: 'MatchInformation',
path: 'info',
component: RoutingControl,
props: (route) => ({
subroutes: getRouteNames("MatchInformation"),
}),
children: [{
name: 'Match info',
path: 'match-info',
component: MatchInfo,
}, {
name: 'match history',
path: 'match-history',
component: MatchHistory,
}, {
name: 'community resources',
path: 'community-resources',
component: CommunityResources,
}],
}
],
}, ]
}
]
// get subroutes automatically for router (by route name)
function getChildrenRoutesNames(arr) {
return (routeName) => {
let ret = []
arr.forEach(route => {
if (route.name === routeName) {
ret = route?.children.map(({
name
}) => name)
} else {
if (route?.children?.length) {
ret = [...ret, ...getChildrenRoutesNames(route.children)(routeName)]
}
}
})
return ret
}
}
// "fixing" the routes array scope, so it stays when used
// inside that array
const getRouteNames = getChildrenRoutesNames(routes)
const router = new VueRouter({
routes,
})
new Vue({
el: "#app",
router,
})
.link {
padding: 0 8px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<div id="app">
<router-view />
</div>
I hope this is close to what you were looking for :)
Upvotes: 1