Vue项目中如何实现按日期范围筛选API返回的表格数据?
日期区间过滤表格数据实现方案
问题描述
开发API项目时,需在表格中展示数据,添加开始/结束日期输入框,点击提交后仅显示date字段在区间内的数据,目前未实现该功能。
现有代码
HTML模板部分
<input style="position: relative; left: 750px" type="date" label="starting date" /> <input style="position: relative; left: 750px" type="date" label="last date" /> <button style="position: relative; left: 750px" type="button" class="btn btn-secondary" > submit dates </button> <hr /> <table class="table table-hover table-striped"> <!--Table Head--> <thead class="thead-dark"> <tr> <th scope="col">ID</th> <th scope="col">apkMode</th> <th scope="col">date</th> <th scope="col">timestamp</th> <th scope="col">user</th> <th scope="col">news</th> <th scope="col">selfEvaluationQuestion</th> <th scope="col">selfEvaluationAnswer</th> <th scope="col">questionQuiz</th> <th scope="col">answerQuiz</th> <th scope="col">quizAnswer</th> <th scope="col">questionQ2</th> <th scope="col">answerQ2</th> <th scope="col">similarityq2</th> <th scope="col">questionQ0</th> <th scope="col">answerQ0</th> </tr> </thead> <tbody> <tr v-for="(session, _id) in sessions" :key="_id"> <td>{{ session._id }}</td> <td>{{ session.apkMode }}</td> <td>{{ session.date }}</td> <td>{{ session.timestamp }}</td> <td>{{ session.user }}</td> <td> <span v-for="(interaction, index) in session.interactions" :key="index" > <p v-if="interaction.type === 'newsCore'"> {{ interaction.text }} </p> </span> </td> <td> <span v-for="(interaction, index) in session.interactions" :key="index" > <p v-if=" interaction.type === 'selfEvaluationQuestion' " > {{ interaction.text }} </p> </span> </td> <td> <span v-for="(interaction, index) in session.interactions" :key="index" > <p v-if=" interaction.type === 'selfEvaluationAnswer' " > {{ interaction.text }} </p> </span> </td> <td> <span v-for="(interaction, index) in session.interactions" :key="index" > <p v-if=" interaction.type === 'questionQuiz' " > {{ interaction.text }} </p> </span> </td> <td> <span v-for="(interaction, index) in session.interactions" :key="index" > <p v-if="interaction.type === 'answerQuiz'" > {{ interaction.text }} </p> </span> </td> <td> <span v-for="(interaction, index) in session.interactions" :key="index" > <p v-if="interaction.type === 'answerQuiz'" > {{ interaction.quizAnswer }} </p> </span> </td> <td> <span v-for="(interaction, index) in session.interactions" :key="index" > <p v-if="interaction.type === 'questionQ2'" > {{ interaction.text }} </p> </span> </td> <td> <span v-for="(interaction, index) in session.interactions" :key="index" > <p v-if="interaction.type === 'answerQ2'"> {{ interaction.text }} </p> </span> </td> <td> <span v-for="(interaction, index) in session.interactions" :key="index" > <p v-if="interaction.type === 'answerQ2'"> {{ interaction.similarity }} </p> </span> </td> <td> <span v-for="(interaction, index) in session.interactions" :key="index" > <p v-if="interaction.type === 'answerQ0'"> {{ interaction.text }} </p> </span> </td> </tr> </tbody> </table>
JavaScript部分
<script> import axios from "axios"; import papa from "papaparse"; export default { data() { return { sessions: [], }; }, methods: { getSessions() { const path = "http://localhost:5000/data_for_front"; axios .get(path) .then((res) => { this.sessions = res.data; papa.parse(this.sessions, { header: true, dynamicTyping: true, skipEmptyLines: true, complete(result) { this.sessions = result.data; }, }); }) .catch((err) => { console.error(err); }); }, }, }; </script>
数据示例
{ "_id" : "userid", "apkMode" : "SCROLL", "date" : "2022-04-25", "timestamp" : 1650913068512, "user" : "username", "interactions" : [ { "interactionTimestamp" : 1650912989260, "subject" : "ROBOT", "type" : "selfEvaluationQuestion", "text" : "questiontext" }, { "interactionTimestamp" : 1650913013738, "subject" : "HUMAN", "type" : "selfEvaluationAnswer", "text" : "questionresponse" }, { "interactionTimestamp" : 1650913022948, "subject" : "ROBOT", "type" : "newsCore", "text" : "newstext" }, { "interactionTimestamp" : 1650913042076, "subject" : "ROBOT", "type" : "questionQ2", "text" : "Q2text" }, { "interactionTimestamp" : 1650913047978, "subject" : "ROBOT", "type" : "questionQ0", "text" : "Q0text" }, { "interactionTimestamp" : 1650913047978, "subject" : "HUMAN", "type" : "answerQ2", "text" : "Q2answer", "similarity" : 0.0, "correctAnswer" : "Q2correctanswer" }, { "interactionTimestamp" : 1650913058686, "subject" : "HUMAN", "type" : "answerQ0", "text" : "Q0answer" }, { "interactionTimestamp" : 1650913058867, "subject" : "ROBOT", "type" : "questionEnd", "text" : "Endquestion" }, { "interactionTimestamp" : 1650913068512, "subject" : "HUMAN", "type" : "answerEnd", "text" : "Endanswer" } ] }
注:已知v-for搭配v-if的性能问题,因数据样本有限,暂采用该方式简化开发。
实现步骤
1. 绑定日期输入框和提交事件
修改HTML模板,给日期输入框添加v-model绑定数据,给按钮添加点击事件:
<input style="position: relative; left: 750px" type="date" label="starting date" v-model="startDate" /> <input style="position: relative; left: 750px" type="date" label="last date" v-model="endDate" /> <button style="position: relative; left: 750px" type="button" class="btn btn-secondary" @click="filterByDate" > submit dates </button>
2. 扩展data属性
在data中添加日期变量和原始数据存储(避免过滤后丢失原数据):
data() { return { sessions: [], originalSessions: [], // 存储原始数据 startDate: '', endDate: '', }; },
3. 修改数据获取逻辑
在getSessions中保存原始数据,若后端返回的是JSON而非CSV,可移除papa.parse逻辑:
getSessions() { const path = "http://localhost:5000/data_for_front"; axios .get(path) .then((res) => { this.originalSessions = res.data; this.sessions = [...this.originalSessions]; // 初始化展示全部数据 // 若后端返回CSV,保留以下解析逻辑,否则删除 // papa.parse(this.sessions, { // header: true, // dynamicTyping: true, // skipEmptyLines: true, // complete: (result) => { // this.originalSessions = result.data; // this.sessions = [...this.originalSessions]; // }, // }); }) .catch((err) => { console.error(err); }); },
4. 实现日期过滤方法
添加filterByDate方法,根据日期区间过滤数据:
methods: { // ... 原有getSessions方法 filterByDate() { if (!this.startDate || !this.endDate) { alert('请选择开始和结束日期'); return; } // 将日期字符串转为Date对象,统一格式后比较 const start = new Date(this.startDate); const end = new Date(this.endDate); // 过滤原始数据,保留date在区间内的项 this.sessions = this.originalSessions.filter(session => { const sessionDate = new Date(session.date); return sessionDate >= start && sessionDate <= end; }); }, },
5. 可选:添加重置功能
若需要恢复展示全部数据,可添加重置按钮和方法:
<button style="position: relative; left: 750px; margin-left: 10px" type="button" class="btn btn-light" @click="resetFilter" > reset </button>
resetFilter() { this.startDate = ''; this.endDate = ''; this.sessions = [...this.originalSessions]; },
关键说明
- 必须保留原始数据副本,避免过滤后无法恢复全部数据
- 日期比较时需统一转为
Date对象,确保格式一致 - 若后端返回JSON数据,无需使用
papa.parse,直接处理即可
内容的提问来源于stack exchange,提问作者wayfarer85
相关产品推荐
相关产品推荐

