繁体   English   中英

如何使用 vue js 过滤日期范围?

[英]How to filter date range using vue js?

我正在学习 vue.js,并且正在尝试使用范围日期的过滤器功能。 场景是:首先按类型过滤,然后按日期范围过滤(有开始日期和结束日期)。 选择结束日期后将显示结果。 我创建了第一个过滤器,它是类型,它可以工作。 我已经搜索了日期范围的各种方法,但仍然找不到合适的方法。 如何使用computedmethods过滤日期范围? 如果有人知道,你能告诉我一步一步吗?

 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>

以下是您可以解决的方法:

  1. 创建startDateendDate作为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);
  2. if - else中的日期比较显式检查null ,但它们的值不会是null因为您正在实例化Date对象。 通过步骤 1 中的更新,日期值为Datefalse ,因此您可以更新比较以检查虚假值而不是null

     if (startDate && endDate) {/*...*/} if (startDate &&.endDate) {/*...*/} if (.startDate && endDate) {/*...*/}
  3. selectedType永远不会是null ,但是您可以检查确定类型是否未指定是否虚假。 在这种情况下,您可以只返回原始数组以避免对Array.prototype.filter的不必要调用:

     const itemsByType = filterType? this.items.filter(item => item.type === filterType): this.items
  4. 由于要将日期显示为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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM