This seems like your run-of-the-mill master/detail use case, but the examples in the Vue docs stop short of examples for this. I have a Mail Folder page (route /:mailbox_id
) that displays a table of emails by Date, Subject, etc., and I want a nested route (/:message_id
) that shows the email's text when the user clicks on a row.
I was able to do this in Ember (recreating this) because Ember makes a JavaScript onClick function to handle the routing and lets you set the HTML element to render, and then you just pass whatever objects to the child route.
But I'm new to Vue.js, and I've been going through the docs but can't grok how to accomplish the same thing. I can't figure out how to either create a custom link component, or how to use the built-in Vue <router-link>
component (because I need it to be a <tr>
instead of <a>
) to both go to the child route, and pass along the contents of the message to it so it can be shown.
If it helps, here's some code:
The Router
export default new Router({
routes: [
{
path: '/:id',
name: 'mailbox',
component: Mailbox,
props: true,
children: [
{
path: 'mail/:id',
name: 'mail',
component: Mail,
props: true
}
]
}
]
})
Component: Mailbox.vue
<template>
<div>
<table>
<tr>
<th>Date</th>
<th>Subject</th>
<th>From</th>
<th>To</th>
</tr>
<Mail-List-Item v-for="message in messages" :key="message.id" v-bind:message="message"/>
</table>
<router-view></router-view>
</div>
</template>
<script>
import MailListItem from './Mail-List-Item'
export default {
components: { 'Mail-List-Item': MailListItem },
name: 'Mailbox',
props: ['messages']
}
</script>
Component: Mail.vue
<template>
<div class="mail">
<dl>
<dt>From</dt>
<dd>{{mail.from}}</dd>
<dt>To</dt>
<dd>{{mail.to}}</dd>
<dt>Date</dt>
<dd>{{messageDate}}</dd>
</dl>
<h4>{{mail.subject}}</h4>
<p>{{mail.body}}</p>
</div>
</template>
<script>
export default {
props: ['message', 'messageDate']
}
</script>
Component: Mail-List-Item.vue
<template>
<V-Row-Link href="mail" mailid="message.id" message="message">
<td>{{messageDate}}</td>
<td>{{message.subject}}</td>
<td>{{message.from}}</td>
<td>{{message.to}}</td>
</V-Row-Link>
</template>
<script>
var moment = require('moment')
import VRowLink from './V-Row-Link'
export default {
name: 'Mail-List-Item',
props: ['message'],
components: { VRowLink },
data: function () {
return {messageDate: moment(this.message.date).format('MMM Do')}
}
}
</script>
Component: V-Row-Link.vue (much of this copied from this repo)
<template lang="html">
<tr
v-bind:href="href"
v-on:click="go"
>
<slot></slot>
</tr>
</template>
<script>
import routes from '../Router'
export default {
props: ['href', 'mailid', 'message'],
methods: {
go (event) {
this.$root.currentRoute = this.href
window.history.pushState(
null,
routes[this.href],
this.href
)
}
}
}
</script>
Router link takes a tag attribute, that you can use to turn it into any element you like. An example would be...
<router-link tag="tr" :to="'/messages/' + MAIL_ID">{{ MAIL_TITLE }}</router-link>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With