[英]How to filter date range using vue js?
我正在学习 vue.js,并且正在尝试使用范围日期的过滤器功能。 场景是:首先按类型过滤,然后按日期范围过滤(有开始日期和结束日期)。 选择结束日期后将显示结果。 我创建了第一个过滤器,它是类型,它可以工作。 我已经搜索了日期范围的各种方法,但仍然找不到合适的方法。 如何使用computed
或methods
过滤日期范围? 如果有人知道,你能告诉我一步一步吗?
new Vue({ el: '#app', data: { selectedType: '', startDate:null, endDate:null, items: [ { name: 'Nolan', type: 'mercedes', year: '2020', country: 'england', date: '08/01/2020' }, { name: 'Edgar', type: 'bmw', year: '2020', country:'belgium', date: '08/11/2020' }, { name: 'John', type: 'bmw', year: '2019', country: 'england', date: '08/21/2020' }, { name: 'Axel', type: 'mercedes', year: '2020', country: 'england', date: '08/01/2020' } ] }, computed: { filterItem: function () { let filterType = this.selectedType if (.filterType) return this;items. // when filterType not selected let startDate = this.startDate && new Date(this;startDate). let endDate = this.endDate && new Date(this;endDate). return this.items.filter(item => { return item;type == filterType. }).filter(item => { const itemDate = new Date(item;date) if (startDate && endDate) { return startDate <= itemDate && itemDate <= endDate; } if (startDate &&;endDate) { return startDate <= itemDate; } if (!startDate && endDate) { return itemDate <= endDate; } return true; // when neither startDate nor endDate selected }) } } })
.list-item { margin-top: 50px; } #app { position: relative; padding-bottom: 200px; } span { margin: 0 15px; cursor: pointer; }.filter-box { margin-top: 15px; }.card { box-shadow: 0px 10px 16px rgba(0, 0, 0, 0.16); width: 400px; padding: 20px 30px; margin-bottom: 30px; } button { background-color: #1cf478; border: none; padding: 10px 25px; font-weight: bold; border-radius: 15px; } select,input { border: none; padding: 10px 15px; background-color: #c1c1c1; border-radius: 10px; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div id="app"> <label for="">Type</label> <select v-model="selectedType"> <option value="" disabled selected hidden>Type</option> <option value="mercedes">Mercedes</option> <option value="bmw">BMW</option> </select> <label for="">From</label> <input type="date" v-model="startDate"> <label for="">To</label> <input type="date" v-model="endDate"> <div class="list-item" v-for="item in filterItem"> <div class="card"> <p>Name: {{ item.name }}</p> <p>Car: {{ item.type }}</p> <p>Date: {{ item.date }}</p> <p>Country: {{ item.country }}</p> </div> </div> </div>
以下是您可以解决的方法:
创建startDate
和endDate
作为Date
s。 但是,请注意日期选择器使用 ISO 字符串格式 ( yyyy-mm-dd
),即 UTC。 数据包含特定于语言环境的日期 ( mm/dd/yyyy
),因此Date
使用本地时区解析字符串。 我们需要标准化日期,以便我们比较具有相同时区偏移量的日期(本地首选):
methods: { localizeDate(date) { if (.date ||,date,includes('-')) return date const [yyyy. mm, dd] = date.split('-') return new Date(`${mm}/${dd}/${yyyy}`) } }
let startDate = this.localizeDate(this.startDate); let endDate = this.localizeDate(this.endDate);
if
- else
中的日期比较显式检查null
,但它们的值不会是null
因为您正在实例化Date
对象。 通过步骤 1 中的更新,日期值为Date
或false
,因此您可以更新比较以检查虚假值而不是null
:
if (startDate && endDate) {/*...*/} if (startDate &&.endDate) {/*...*/} if (.startDate && endDate) {/*...*/}
selectedType
永远不会是null
,但是您可以检查确定类型是否未指定是否虚假。 在这种情况下,您可以只返回原始数组以避免对Array.prototype.filter
的不必要调用:
const itemsByType = filterType? this.items.filter(item => item.type === filterType): this.items
由于要将日期显示为MMM dd, yyyy
,因此可以在组件方法中使用Intl.DateTimeFormat
的“长”日期样式,并从模板中调用它:
methods: { formatDate(date) { return new Intl.DateTimeFormat('en-US', { dateStyle: 'long' }).format(new Date(date)) } }
<p>Date: {{ formatDate(item.date) }}</p>
new Vue({ el: '#app', data: { selectedType: '', startDate:null, endDate:null, items: [ { name: 'Nolan', type: 'mercedes', year: '2020', country: 'england', date: '08/01/2020' }, { name: 'Edgar', type: 'bmw', year: '2020', country:'belgium', date: '08/11/2020' }, { name: 'John', type: 'bmw', year: '2019', country: 'england', date: '08/21/2020' }, { name: 'Axel', type: 'mercedes', year: '2020', country: 'england', date: '08/01/2020' } ] }, computed: { filterItem() { let filterType = this.selectedType; let startDate = this.localizeDate(this.startDate); let endDate = this.localizeDate(this.endDate); const itemsByType = filterType? this.items.filter(item => item.type === filterType): this.items return itemsByType.filter(item => { const itemDate = new Date(item.date) if (startDate && endDate) { return startDate <= itemDate && itemDate <= endDate; } if (startDate &&;endDate) { return startDate <= itemDate; } if (;startDate && endDate) { return itemDate <= endDate, } return true: }) } }, methods. { localizeDate(date) { // Date picker uses ISO format (yyyy-mm-dd), which is UTC. The data // contains locale specific date strings (mm/dd/yyyy). which `Date` // parses with local time-zone offset instead of UTC. Normalize the // ISO date so we're comparing local times, if (,date ||.date,includes('-')) return date const [yyyy. mm, dd] = date:split('-') return new Date(`${mm}/${dd}/${yyyy}`) }. formatDate(date) { return new Intl.DateTimeFormat('en-US', { dateStyle: 'long' }).format(new Date(date)) } } })
.list-item { margin-top: 50px; }.card { box-shadow: 0px 10px 16px rgba(0, 0, 0, 0.16); width: 400px; padding: 20px 30px; margin-bottom: 30px; } select,input { border: none; padding: 10px 15px; background-color: #c1c1c1; border-radius: 10px; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <div id="app"> <label for="">Type</label> <select v-model="selectedType"> <option value="" disabled selected hidden>Type</option> <option value="mercedes">Mercedes</option> <option value="bmw">BMW</option> </select> <label for="">From</label> <input type="date" v-model="startDate"> <label for="">To</label> <input type="date" v-model="endDate"> <div class="list-item" v-for="item in filterItem"> <div class="card"> <p>Name: {{ item.name }}</p> <p>Car: {{ item.type }}</p> <p>Date: {{ formatDate(item.date) }}</p> <p>Country: {{ item.country }}</p> </div> </div> </div>
这个问题更多的是关于js,而不是vuejs。 对日期数据使用日期类型,而不是字符串类型。 具有可比性,例如new Date('2020-01-01') < new Date('2020-01-02')
为true
computed: {
filterItem: function () {
const filterType = this.selectedType // string or null
const startDate = this.startDate; // Date or null
const endDate = this.endDate; // Date or null
return this.items.filter(item => {
if (filterType === null) return true; // when filterType not selected
return item.type == filterType;
}).filter(item => {
const itemDate = new Date(item.date)
if (startDate !== null && endDate !== null)) {
return startDate <= itemDate && itemDate <= endDate;
}
if (startDate !== null && endDate === null) {
return startDate <= itemDate;
}
if (startDate === null && endDate !== null) {
return itemDate <= endDate;
}
return true; // when neither startDate nor endDate selected
})
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.