programing

vue js를 사용하여 날짜 범위를 필터링하려면 어떻게 해야 합니까?

sourcetip 2022. 8. 28. 12:26
반응형

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>

이 문제를 해결하는 방법은 다음과 같습니다.

  1. 만들다startDate그리고.endDate~하듯이Dates. 단, 달력 선택기는 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의 업데이트에서는 날짜 값은 다음 중 하나입니다.Date또는false비교를 갱신하여 위변조 값을 체크할 수 있습니다.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컴포넌트 메서드에서 의 "긴" 날짜 스타일을 사용하여 템플릿에서 호출할 수 있습니다.

    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>

이 질문은 vuejs가 아니라 js에 관한 것입니다.날짜 데이터에 문자열 유형이 아닌 날짜 유형을 사용합니다.예를 들어 비교가 됩니다.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
      })
    }

언급URL : https://stackoverflow.com/questions/66193339/how-to-filter-date-range-using-vue-js

반응형