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

VueJS中如何通过起止年月下拉菜单实现表格数据筛选?

嘿,作为Vue新手碰到时间范围筛选的问题太正常啦!我来一步步帮你捋清楚怎么实现,结合你说的四个下拉菜单(起始年、起始月、结束年、结束月)和SQLite数据的情况,咱们分步骤来:

第一步:前端下拉菜单的绑定与数据准备

首先得把下拉菜单和Vue的数据绑定起来,同时生成年份、月份的选项:

  • 在data里定义四个变量:startYear、startMonth、endYear、endMonth,默认可以设为当前年月
  • 生成年份选项(比如最近10年)和月份选项(1-12,格式统一为两位数字,比如01、02)
  • 用v-model把下拉菜单和这些变量绑定,确保选中值能实时同步到Vue实例
第二步:实现时间范围筛选逻辑

筛选逻辑有两种方式,根据你的数据量选:

方式一:前端全量筛选(适合数据量小的情况)

用Vue的computed属性自动计算筛选后的数据,这样当下拉框的值变化时,表格会自动更新:

  • 把从SQLite获取的原始数据存在originalData里
  • 在computed里写filteredData,将每条数据的年月转换成YYYY-MM格式的字符串,和选中的起始、结束年月字符串做比较(因为YYYY-MM格式的字符串可以直接按字典序比较大小)
  • 表格循环渲染filteredData就行

方式二:数据库层面筛选(适合数据量大的情况)

如果数据量比较多,前端全量筛选会慢,建议直接在SQLite查询时加时间范围条件:

  • 监听下拉框的变化,每次选中值改变时,调用方法重新查询数据库
  • 用SQLite的strftime函数处理日期,比如WHERE strftime('%Y-%m', date_column) BETWEEN ? AND ?,把选中的起始年月(YYYY-MM)和结束年月作为参数传入
第三步:添加时间范围校验

避免用户选的结束时间早于起始时间,可以加个校验逻辑:

  • 用watch监听四个下拉框的变化,每次变化时比较起始时间和结束时间
  • 如果结束时间更早,弹出提示或者自动调整结束时间为起始时间
完整代码示例整合
<template>
  <div class="container">
    <!-- 时间筛选下拉框 -->
    <div class="time-filter">
      <select v-model="startYear">
        <option v-for="year in yearOptions" :key="year" :value="year">{{ year }}</option>
      </select>
      <select v-model="startMonth">
        <option v-for="month in monthOptions" :key="month" :value="month">{{ month }}</option>
      </select>
      <span> 至 </span>
      <select v-model="endYear">
        <option v-for="year in yearOptions" :key="year" :value="year">{{ year }}</option>
      </select>
      <select v-model="endMonth">
        <option v-for="month in monthOptions" :key="month" :value="month">{{ month }}</option>
      </select>
    </div>

    <!-- 数据表格 -->
    <table class="data-table">
      <thead>
        <tr>
          <th>日期</th>
          <th>其他字段</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="item in filteredData" :key="item.id">
          <td>{{ item.date }}</td>
          <td>{{ item.otherField }}</td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

<script>
export default {
  data() {
    return {
      // 时间筛选变量
      startYear: new Date().getFullYear(),
      startMonth: String(new Date().getMonth() + 1).padStart(2, '0'),
      endYear: new Date().getFullYear(),
      endMonth: String(new Date().getMonth() + 1).padStart(2, '0'),
      // 原始数据(从SQLite获取)
      originalData: [],
      // 年份选项(最近10年)
      yearOptions: [],
      // 月份选项(两位数字)
      monthOptions: Array.from({ length: 12 }, (_, i) => String(i + 1).padStart(2, '0'))
    };
  },
  computed: {
    // 前端筛选后的数据集
    filteredData() {
      const startDateStr = `${this.startYear}-${this.startMonth}`;
      const endDateStr = `${this.endYear}-${this.endMonth}`;

      return this.originalData.filter(item => {
        // 假设item.date是YYYY-MM-DD格式,取前7位得到YYYY-MM
        const itemDateStr = item.date.substring(0, 7);
        return itemDateStr >= startDateStr && itemDateStr <= endDateStr;
      });
    }
  },
  mounted() {
    // 生成年份选项
    const currentYear = new Date().getFullYear();
    this.yearOptions = Array.from({ length: 10 }, (_, i) => currentYear - i);
    // 初始化从SQLite获取数据
    this.fetchOriginalData();
  },
  watch: {
    // 监听时间筛选变量变化,校验时间范围
    startYear: 'validateDateRange',
    startMonth: 'validateDateRange',
    endYear: 'validateDateRange',
    endMonth: 'validateDateRange'
    // 如果用数据库筛选,把上面换成:
    // startYear: 'fetchFilteredDataFromDB',
    // startMonth: 'fetchFilteredDataFromDB',
    // endYear: 'fetchFilteredDataFromDB',
    // endMonth: 'fetchFilteredDataFromDB'
  },
  methods: {
    // 从SQLite获取全量数据(示例,根据你的实际SQLite使用方式调整)
    async fetchOriginalData() {
      // 如果你是在Electron环境用sqlite3:
      // const sqlite3 = require('sqlite3').verbose();
      // const db = new sqlite3.Database('./your-database.db');
      // db.all('SELECT * FROM your-table', (err, rows) => {
      //   if (!err) this.originalData = rows;
      //   db.close();
      // });

      // 如果是通过后端接口获取数据:
      // const res = await axios.get('/api/your-data');
      // this.originalData = res.data;
    },
    // 从SQLite筛选数据(适合大数据量)
    async fetchFilteredDataFromDB() {
      const startDateStr = `${this.startYear}-${this.startMonth}`;
      const endDateStr = `${this.endYear}-${this.endMonth}`;
      // const sqlite3 = require('sqlite3').verbose();
      // const db = new sqlite3.Database('./your-database.db');
      // db.all(
      //   `SELECT * FROM your-table WHERE strftime('%Y-%m', date_column) BETWEEN ? AND ?`,
      //   [startDateStr, endDateStr],
      //   (err, rows) => {
      //     if (!err) this.originalData = rows;
      //     db.close();
      //   }
      // );
    },
    // 校验时间范围是否合法
    validateDateRange() {
      const start = new Date(`${this.startYear}-${this.startMonth}`);
      const end = new Date(`${this.endYear}-${this.endMonth}`);
      if (start > end) {
        alert('结束时间不能早于起始时间哦!');
        // 自动调整结束时间为起始时间
        this.endYear = this.startYear;
        this.endMonth = this.startMonth;
      }
    }
  }
};
</script>

<style scoped>
.time-filter {
  margin-bottom: 20px;
}
.data-table {
  border-collapse: collapse;
  width: 100%;
}
.data-table th, .data-table td {
  border: 1px solid #ddd;
  padding: 8px;
  text-align: left;
}
</style>
几个关键注意事项
  • 日期格式统一:确保SQLite里的日期字段格式是标准的(比如YYYY-MM-DD),这样前端处理或者SQL查询都不会出错
  • 月份格式:一定要把月份处理成两位数字(比如01而不是1),不然字符串比较的时候会出现2024-1 > 2024-10的错误
  • 性能选择:数据量小(比如几百条)用前端筛选就行,数据量大(几千条以上)尽量用数据库层面筛选,减少前端压力

如果还有具体的细节比如SQLite的使用方式、数据格式不匹配之类的问题,随时调整就行!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:35:41