因为公司项目需要在账单中做账单筛选功能,要求有年月日筛选,有近一年,半年,一个月的日历快捷筛选要求
总之需求就是参考支付宝账单日历筛选
找了一圈各方插件,没有特别合适的,索性时间还算充裕,自己搞一个
插件中使用到了moment.js时间插件,我这里主要用到的就是获取日期数据和计算就近时间,具体文档大家可以参考官方文档,文档地址Moment.js | Docs
大致的实现思路与代码,弹窗什么的巴拉巴拉的就不说了,都是废话
1. 弹出筛选框先默认显示月份筛选选项,默认选择到本月,这个实现起来比较简单直接获取筛选区间年份(比如筛选区间为2022 - 2023年直接搞一个数组循环2022..2023即可),以及当前年月,使用picker-view滑块组件搞一个滚动筛选项,并默认到当年当月(也就是数组的长度-1)
我实现当前部分的代码如下:
const monthYM = { years: [], months: [] }
const monthValue = [ 0, 0 ]
for(let i = 2022; i <= moment().get('year'); i++){
monthYM.years.push(i)
}
for(let i = 1; i <= (moment().get('month') + 1); i++){
monthYM.months.push(i)
}
monthValue[0] = monthYM.years.length - 1;
monthValue[1] = monthYM.months.length - 1;
2. 月份筛选这里功能都比较简单,直接使用picker-view@change事件获取选择的月份即可,这里需要注意的是如果选择的非本年这里需要初始化一下monthYM对象中months的月份数据,因为第一次获取数据的时候的日期是非完整的1-12月数据
代码如下:
let { value } = e.detail
let atMonthVal = this.monthValue
let yearVal = this.monthYM.years[value[0]]
let isAtYear = yearVal == moment().get('year')
let monthsArr = []
if(value[0] != atMonthVal[0]){
for(let i = 1; i <= Number(isAtYear ? moment().get('month') + 1 : 12); i++ ){
monthsArr.push(i)
}
this.$set(this.monthYM, 'months', monthsArr)
}
this.monthValue = value
到了这里我们就可以直接使用monthValue和monthYM两个数据来获取到用户选中的月份了,可以根据后端接口进行一下简单的区间数据格式化,这里就不在赘述了;
月份筛选也就搞定了下面在搞一下自定义时间的筛选,这里包含了最近1个月,最近6个月以及最近1年的数据快捷筛选和年月日筛选
有了第一部分第二部分功能其实也就很容易实现了下面直接垒实现思路以及代码
3. 这里我们需要两个新的页面数组来承载年月日的数据,也就是当用户选择点击TAB栏的时候进行获取这里分为了开始时间和结束时间两个数据源数组以及两个筛选结果数组,点击切换后直接默认获取开始时间为当前年月日并使用picker-view滑块来显示当前的可选时间段这里时间段直接参考日期获取方式基本一直只是多了按照年月获取日期天数而已,下面直接看代码
// 切换tab后获取初始化时间
let { Ymd, Val, Date } = this.getAtData()
this.startYMD = Ymd
this.startValue = Val
this.startDate = Date
// 初始化时间方法,因为这段功能在获取结束时间时候也会应用所以直接搞一个方法单独处理
getAtData(){
let Ymd = { years: [], months: [], days: [] }
let Val = [ 0,0,0 ]
let Date = ''
for(let i = 2022; i <= moment().get('year'); i++){
Ymd.years.push(i)
}
for(let i = 1; i <= (moment().get('month') + 1); i++){
Ymd.months.push(i)
}
for(let i = 1; i <= moment().get('date'); i++){
Ymd.days.push(i)
}
Val[0] = Ymd.years.length - 1
Val[1] = Ymd.months.length - 1
Val[2] = Ymd.days.length - 1
let year = Ymd.years[Val[0]];
let month = Ymd.months[Val[1]];
let day = Ymd.days[Val[2]]
Date = year + '-' + (month <= 9 ? '0' + month : month ) + '-' + (day <= 9 ? '0' + day : day )
return { Ymd, Val, Date }
}
4. 这样默认好了开始时间,接下来结束时间参考开始时间,这里直接看代码,就不在赘述
let years = []
let values = [ 0, 0, 0 ]
let endDateArr = this.endDate.split('-')
let { months, days } = this.getNewYM(endDateArr[0], endDateArr[1])
for(let i = 2022; i <= endDateArr[0]; i++){
years.push(i)
}
values[0] = years.length - 1
values[1] = months.length - 1
values[2] = days.length - 1
this.endYMD = { years, months, days}
this.endValue = values
// 获取最新结束的年月日
getNewYM(year, month){
let months = []
let days = []
let lastDay = new Date(year, month, 0).getDate()
if(year == moment().get('year') && month == moment().get('month') + 1){
lastDay = moment().get('date')
}
for(let i = 1; i <= (year == moment().get('year') ? moment().get('month') + 1 : 12); i++){
months.push(i)
}
for(let i = 1; i <= lastDay; i++){
days.push(i)
}
return { months, days }
},
5. 到这里自定义时间段筛选功能也就完成了,下面来说一下就近时间的筛选,因为就近时间需要计算的当前日期向前的日期,这里如果直接使用picker-view的value数据计算会不够准确,所以需要获取最新年月日数据并使用moment().subtract(num, type)获取向前的日期,之后通过findIndex获取向前日期在picker-view中粒子的位置;并将粒子滚动到该位置;
方法实现直接看代码
let year = moment().get('year')
let month = moment().get('month') + 1
let today = moment().get('date')
let start = moment().subtract(num, 'month').format('YYYY-MM-DD')
let ymdArr = start.split('-')
let { months, days } = this.getNewYM(ymdArr[0], ymdArr[1])
this.$set(this.startYMD, 'months', months)
this.$set(this.startYMD, 'days', days)
let yearIndex = this.startYMD.years.findIndex(val => val == ymdArr[0]) || 0
let monthIndex = this.startYMD.months.findIndex(val => val == ymdArr[1]) || 0
let dayIndex = this.startYMD.days.findIndex(val => val == ymdArr[2]) || 0
this.startValue = [yearIndex, monthIndex, dayIndex]
this.startDate = start
this.endDate = year + '-' + (month <= 9 ? '0' + month : month ) + '-' + (today <= 9 ? '0' + today : today )
if(this.dateTypeKey == 'end'){
let years = []
let values = [ 0, 0, 0 ]
let endDateArr = this.endDate.split('-')
let { months, days } = this.getNewYM(endDateArr[0], endDateArr[1])
for(let i = 2022; i <= endDateArr[0]; i++){
years.push(i)
}
values[0] = years.length - 1
values[1] = months.length - 1
values[2] = days.length - 1
this.endYMD = { years, months, days}
this.endValue = values
}
到这里也就大致实现了时间筛选的功能;下面为效果预览
仿支付宝账单筛选组件
第一次发文章,有不足欢迎指出