Reputation: 93
I'm trying to understand how to use values in a Vuex store and do some formatting, critically I'm trying to figure out the Vue way of formatting a timestamp contained within an object in the store and while iterating over the object.
For example using the following store
const state = {
events: {
0: {
id: 0,
name: 'Example Event',
start: 14907747374,
end: 14907747674,
entries: [0, 1]
},
1: {
id: 1,
name: 'Example Event 2',
start: 14907740364,
end: 14907740864,
entries: [1]
}
},
entries: {
0: {
id: 0,
name: 'John Doe',
},
1: {
id: 1,
name: 'Paul Smith'
}
}
}
I then have a getter to return all the events
export const events = state => state.events
And then I want to display the events as a list/table etc in component
<template>
<div class="events">
<template v-for="event in getAllEvents">
<div class="event>
{{ event.name }} || {{ event.start }}
</div>
</template>
</div>
</template>
<script>
export default {
name: 'events',
computed: {
getAllEvents: function () {
return this.$store.state.events
}
}
}
</script>
So this would display
Example Event || 14907747374
Example Event 2 || 14907740864
whereas I need to display
Example Event || Jan 3rd 2017 14:15
Example Event 2 || Jan 3rd 2017 14:45
So within the v-for I want to format the 'event.start' timestamp into a human readable date and this where I'm not sure which method is the Vue way of doing it.
I've done similar before with Angular 1 filters, however my understanding of Vue Filters is they are specific to Components whereas they were available everywhere in Angular 1. Formatting the date seems like a common task that I should be able to write a single function and use it everywhere required. I could write the function in another module and import it into the the Component but I would still need to write the filter in each component where I wish to use it but at least the logic would be separate.
Same issues as the filters here, logic can be separate function but I still have duplication of the filters themselves
Probably the best solution I've thought of but it feels like a misuse of Components for such minor function
<template>
<span>{{ formattedDate }}</span>
</template>
<script>
import 'moment'
export default {
name: 'humanDate',
props: ['timestamp'],
computed: {
formattedDate: function () {
return moment(timestamp).format()
}
}
}
</script>
Then using the component as such
<human-date timestamp="event.start"></human-date>
Is there a better way that I'm missing and is creating components for small things such as this a reasonable use of components?
Upvotes: 2
Views: 2315
Reputation: 14677
Look into Mixins. I created a quick-n-dirty mixin for formatting dates using moment.js:
import moment from 'moment'
export default {
formatDateMixin: {
methods: {
formatDate: function(value) {
if( !value) return '';
return moment(value).format('YYYY-MM-DD HH:mm:ss');
}
}
}
}
Plug it into your main Vue instance:
Vue.mixin(formatDateMixin);
And now you can use it in any template:
{{ event.name }} || {{ formatDate(event.start) }}
Upvotes: 5