If you've used Vue for any length of time, you soon find that it doesn't have a lot of the fancy formatting options that some of the other frameworks seem to have out of the box. I get the feeling that Vue is very focused on minimalism and adding features that aren't core to the framework is not something they want to do. One of those features, however, is formatting dates.
Have you ever had an ugly date from your data source formatted like "2019-07-16T20:32:21"
and thought, "What's the most straightforward way to make this not unreadable?"
My first thought was to use a computed property, but I quickly found that doesn't work very well. If I have a date nested down in an array of objects, I can't really format that using a computed property.
My next thought was to use a method in the component. But date formatting is a very common issue. I don't want to solve it in one component, I want to solve it in all of my components.
I could loop through the data and create a new property on the object to hold the formattedCreateDate
and the formattedUpdateDate
, but then I have to recalculate all of those every time I get a new set of data. That sounds like crying to me. Why am I saving new data in order to change the view of that data? Nope, that goes against all the computery sciencey stuff I've ever learned.
Arg.
So I looked around. What was the "right" answer? Something that was easy and straightforward and, more importantly, reusable and maintainable in one place.
Vue Filters
This is when I found out that Vue has filters. Filters are little UI helper methods that allow you to quickly format data right in the view. Filters look something like this:
{{ name | capitalize }}
Where name
is the variable name and capitalize is a filter that takes the value in name and formats it. Then the mustache expression will show the result of the capitalize filter.
I didn't know Vue even supported these. Every other view framework I've ever used has this feature so it's really not something I'm surprised about, but Vue does not really tout them very much. They are hidden far down in the Vue documentation, but supported they are.
This is the kind of set up I want for dates. I have the data and just want to format it differently for this view.
A Simple Date Filter for Vue
So the simple answer is, use a filter that handles dates. Here's one: https://github.com/eduardnikolenko/vue-filter-date-format
This filter will take your date and spit it out in a specified format. First, you'll need a Date object. If you aren't storing your dates in your data properties as Date object, you can use https://github.com/eduardnikolenko/vue-filter-date-parse to convert a date string in an object.
{{ '2019-07-16' | dateParse('YYYY-MM-DD') }}
And then use the dateFormat
filter to show the date in a more user friendly way:
{{ '2019-07-16' | dateParse('YYYY-MM-DD') | dateFormat('MMMM D, YYYY') }}
The nice thing about these filters is that they don't pull in any extra libraries. They are extremely light weight, just holding the filter functions that use the standard JavaScript Date object functions. 1
This covers about 90% of my date needs and doesn't bloat my code. But what if you need something a little more beefy?
A More Complex Date Filter in Vue
The big woohoo of date libraries in JavaScript is Moment.js. Moment.js can do anything. If you're looking for date formats like 2 hours ago
or Last Saturday at 9:00 PM
, then you'll need something like Moment.js. Luckily, there is a handy filter that uses Moment.js too and will give you all of that amazing functionality:
{{ '2019-07-16' | moment('from', 'now') }}
I wouldn't use this filter unless you absolutely need this kind of advanced functionality. Moment.js is not a small library and loading it in to your web page just to do simple date manipulations just isn't worth it.
All of these install from NPM and import right in your main.js
file. They also have excellent documentation, so check them out and solve all of your Vue date problems for good.
-
You can take a look at the filter function here. ↩
Top comments (6)
You can also define a global filter for using in all components:
Tested on single file components. Perhaps is the same with CDN version.
Yes. The filters are pretty handy. I'm planning writing a post about them soon. Thank you for pointing this out!
Wow! This could have saved me a bunch of time 😅 I've been using moment imported separately in my app 🙃
I was the same way! I think Moment is the answer everyone gives, but it's so much overkill for simple date formatting. I hope you find this useful for future projects!
Surprised to see no mention of Intl. :) I wrote up an article on using Vue with it: vuejsdevelopers.com/2018/03/12/vue...
I've used moment.js it's awesome!