Okay this is going to be a short one 🙂
Momentjs is, without a doubt, the best JavaScript library for handling date and time objects. The first time I tried to use it with Vue though I was greeted with the following message:
"Property or method "moment" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option"
The reason why I got this message was because I was using moment in the view, in my .html file within Vue’s {{}} delimiters. Let’s demonstrate this with a simple example.
In the fiddle above we have a simple Vue instance with a list of posts that will be displayed in a simple table for approval. Everything is simple. We use v-for loop to get each post and then display its data in the table columns. But the postedAt field is a date! We can’t trust JavaScript to convert our date to a string otherwise it will look awful with all the added stuff like time zones. Let’s say we want to just format the date using a DD-MM style, meaning that we only want to display the day and month. Nothing else. What comes to every developer’s mind is, of course, the moment library. So that’s what we do. We import moment using whatever tool we want, yarn, NPM, jspm, pure script tag with a CDN URL. Just about anything will do. Then assuming that what’s inside the curly brackets is JavaScript code, we attempt to run the example…. Aaaand we get the error mentioned above. You can actually see it in the console.
Why is this happening?
It’s all a matter of “this” binding. Notice that whenever you display something in your View that comes from the view-model you do not use the ‘this’ keyword like you do inside the view-model. That’s because the view is tied to the view-model and the use of ‘this’ is not needed. Imagine if you had to use ‘this’ in your HTML. That would be awful. The moment instance is not in our view-model. It’s in the global object, window in this case . “So let’s just go ahead and put a ‘window’ keyword in front of moment”, you might say. Not so fast. The window object is in the global scope too. So you’ll get the same error.
What can we do to remedy this?
We need to include a reference of the moment function in our view-model. The solution is actually pretty straightforward. Just add this line
moment: moment
either in the ‘data’ object or in the ‘methods’ object of your view-model. And that’s it. It’It’s going to work. What we essentially did was to delegate moment through our view-model. See the working example:
And there you have it! Momentjs up and running with Vue in no time.