Reputation: 41
I'm learning vujs and got stuck on my own example with filter and date comparison. I got two similar strings (as dates '2020-02-02') in second row, and I should see the word 'today', but it doesn't work.
why on typeof
in template my dates with filter are numbers?
what I'm doing wrong with comparison those dates? it's always false
.
code you can see down here or https://jsfiddle.net/2awtdny4/9/
html:
<div id="app">
<div v-for="item in info">
<div>
<!-- I compare 2 dates as strings, and if it's true, I want to show word 'Today' -->
<span v-if="(item.date | yymmdd === todayIs | yymmdd)" class="today">today</span>
<!-- else I want to show date as yyyy-mm-dd -->
<span v-else>{{item.date | yymmdd}}</span>
<!-- for some reason with filter date is NUMBER. why? in method and filter they should be stings -->
<span>{{ typeof (item.date | yymmdd)}}</span>
<span>{{ typeof (todayIs)}}</span>
</div>
</div>
</div>
vue:
new Vue({
el: "#app",
data: {
info: [
{ date: "2020-02-01 10:00", text: "first text" }, // date format from backend
{ date: "2020-02-02 15:00", text: "second text" },
{ date: "2020-02-03 15:00", text: "third text" },
{ date: "2020-02-04 18:00", text: "fourth text" },
],
todayIs: null
},
methods: {
today() {
var today = new Date(),
todayDate = ('0'+today.getDate()).slice(-2),
todayMonth = ('0'+ (today.getMonth() + 1) ).slice(-2),
todayYear = today.getFullYear();
var day = '';
day = todayYear + '-' + todayMonth + '-' + todayDate;
this.todayIs = day;
}
},
filters: {
// cut yyyy-mm-dd format and return date as string
'yymmdd': function (date) {
var newDay = new Date(date),
currentDate = ('0'+newDay.getDate()).slice(-2),
currentMonth = ('0'+ (newDay.getMonth() + 1) ).slice(-2),
currentYear = newDay.getFullYear();
var day = '';
day = currentYear + '-' + currentMonth + '-' + currentDate;
return day;
}
},
created: function () {
this.today()
},
})
Upvotes: 0
Views: 4083
Reputation: 37793
You can not use filters like this. If you take a look at the browser console for your linked example, its is full of warnigns:
vue.js:634 [Vue warn]: Property or method "yymmdd" is not defined on the instance but referenced during render.
It is because filters are usable in two places: mustache interpolations and v-bind expressions (the latter supported in 2.1.0+). Filters should be appended to the end of the JavaScript expression, denoted by the “pipe” symbol
Convert your filter to regular method and use computed property to convert your data one time instead of handling conversion in template (on every render)
methods: {
convertDate(d) {
// conversion
}
},
computed: {
convertedData() {
return this.info.map(i => ({ ...i, date: this.convertDate(i.date)}))
}
}
Upvotes: 1
Reputation: 2889
You can use filters
only in mustache interpolations and v-bind expressions (the latter supported in 2.1.0+). Therefore it cannot be used like you have used it in the v-if
.
You can create a function in your methods for comparing dates like the following :
compareWithToday(date){
return this.$options.filters.yymmdd(date) === this.todayIs;
}
And then use this function to evaluate your v-if
flag in template
<span v-if="(item.date | yymmdd === todayIs | yymmdd)" class="today">today</span>
Above should be replaced with the following :
<span v-if="compareWithToday(item.date)" class="today">today</span>
Here is the working jsfiddle of above : https://jsfiddle.net/17mp6ofe/
Reference for filters : https://v2.vuejs.org/v2/guide/filters.html
Upvotes: 1