You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue.js中动态过滤数据并按日期分组展示的实现方案

按日期分组展示事件数据的最优实现方案

需求说明

  • 按日期分组展示事件,每个日期标题下显示对应事件列表
  • 日期需显示为「X月X日 周X」格式(如2月15日 周三)
  • 新增事件时自动归入对应日期分组,无需手动调整

事件数据结构

从API获取的events.data是对象数组,每个事件结构如下:

{
  _id: "63e1330539560eaef2612f84",
  event_date: "2023-02-16T14:00:00.000Z",
  event_link: "/testLink",
  event_name: "TestName",
  price: 12
}

原有实现的问题

你之前用嵌套v-for加v-if的方式,会导致每个日期分组下为所有事件生成div,不符合条件的就变成空DOM节点,既浪费性能又冗余。

最优实现方案

核心思路是先把事件数据按日期预分组为结构化数据,再直接渲染分组结果,彻底去掉模板里的v-if,同时保证响应式更新。

1. 数据分组处理(响应式)

在Vue组件中用计算属性处理分组,这样数据变化时会自动重新计算分组:

Vue3 示例

import { ref, computed } from 'vue'

// 存储从API获取的事件数据,用ref保证响应式
const events = ref([])

// 按日期分组的计算属性
const groupedEvents = computed(() => {
  const dateGroups = {}
  
  events.value.forEach(event => {
    const dateObj = new Date(event.event_date)
    // 生成分组用的唯一日期键(如"2023-02-15")
    const dateKey = dateObj.toLocaleDateString('zh-CN', { 
      year: 'numeric', 
      month: '2-digit', 
      day: '2-digit' 
    })
    // 生成页面显示的日期文本(如"2月15日 周三")
    const displayText = dateObj.toLocaleDateString('zh-CN', {
      month: 'numeric',
      day: 'numeric',
      weekday: 'short'
    })

    // 初始化分组
    if (!dateGroups[dateKey]) {
      dateGroups[dateKey] = {
        displayText,
        eventList: []
      }
    }
    // 将事件加入对应分组
    dateGroups[dateKey].eventList.push(event)
  })

  // 将分组对象转为数组,并按日期排序(早的在前)
  return Object.values(dateGroups).sort((a, b) => {
    const dateA = new Date(Object.keys(dateGroups).find(k => dateGroups[k] === a))
    const dateB = new Date(Object.keys(dateGroups).find(k => dateGroups[k] === b))
    return dateA - dateB
  })
})

Vue2 示例

export default {
  data() {
    return {
      events: [] // 存储API获取的事件数据
    }
  },
  computed: {
    groupedEvents() {
      const dateGroups = {}
      
      this.events.forEach(event => {
        const dateObj = new Date(event.event_date)
        const dateKey = dateObj.toLocaleDateString('zh-CN', { 
          year: 'numeric', 
          month: '2-digit', 
          day: '2-digit' 
        })
        const displayText = dateObj.toLocaleDateString('zh-CN', {
          month: 'numeric',
          day: 'numeric',
          weekday: 'short'
        })

        if (!dateGroups[dateKey]) {
          dateGroups[dateKey] = {
            displayText,
            eventList: []
          }
        }
        dateGroups[dateKey].eventList.push(event)
      })

      return Object.values(dateGroups).sort((a, b) => {
        const dateA = new Date(Object.keys(dateGroups).find(k => dateGroups[k] === a))
        const dateB = new Date(Object.keys(dateGroups).find(k => dateGroups[k] === b))
        return dateA - dateB
      })
    }
  }
}

2. 模板渲染

直接遍历分组后的数据,模板简洁无冗余:

<div v-for="group in groupedEvents" :key="group.displayText">
  <!-- 日期标题 -->
  <div class="date-title">{{ group.displayText }}</div>
  <!-- 分隔线 -->
  <hr class="date-separator" />
  <!-- 事件列表 -->
  <div v-for="event in group.eventList" :key="event._id" class="event-item">
    <a :href="event.event_link" class="event-name">{{ event.event_name }}</a>
    <span class="event-price">价格:{{ event.price }}元</span>
    <!-- 其他事件字段按需渲染 -->
  </div>
</div>

3. 新增事件的自动分组

因为events是响应式数据,当你从API获取新事件并添加到events数组时,groupedEvents计算属性会自动重新执行分组逻辑,新事件会被自动归入对应日期分组,页面无需手动刷新。

方案优势

  • 无冗余DOM:只渲染对应日期的事件,不会生成空div
  • 性能更优:分组逻辑仅在数据变化时执行,避免模板层的重复遍历
  • 逻辑清晰:数据处理和视图渲染分离,代码更易维护
  • 自动响应:新增事件时自动完成分组,无需额外处理

内容的提问来源于stack exchange,提问作者Nehrz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 23:25:27