这个需求是一个独立出来的,没有他的接口。在页面的左上角,有一个antd的时间选择框,有起止时间。在页面的右边,是一个查询按钮,点击查询按钮之后,页面就筛选出符合标准的数据
其实除了日期筛选,之前还有一个类型筛选,再加上本页面的数据是通过接口调的,而其中的请求参数是状态,0,1,2,3.所以正好可以获取到类型筛选的值,直接去放参数里,从而筛选页面的渲染数据。
但是这个时间选择框的话,只是去对数据中的一条,也就是时间进行筛选,不是调接口。所以我就先想了一个大概流程。
// 先声明一个变量,默认值为空,当时间选择之后,把起止时间戳放进变量里(参数1,开始时间,参数2,结束时间),查询按钮,点击的时候
//判断此变量是否为空,为空就直接调用页面渲染方法,否的话把渲染之后的参数循环,筛选。留下复合标准的数据,再调用dataSource方法,其参数就是之前留下来的值。最后每次修改时间时,更改dataSource。实现动态变化。其优先级高于类型筛选。
这里面后来总结的一个很关键的点,就是dayjs里面有个插件是可以进行日期比较的,这个在后面为我实现筛选逻辑判断提供了帮助。
先从第一步开始,声明一个变量,哦对,其实是两个变量
const [searchDateStart, setSearchDateStart] = useState<any>(2022 - 1 - 1) //展示選中時間内的數據(開始)
const [searchDateEnd, setSearchDateEnd] = useState<any>(2122 - 1 - 1) //展示選中時間内的數據(結束)
对了,我还给他们设置了默认值。这样就算一开始的时候他们能正常显示所有数据。先来看日期选择框内的功能
<Form.Item
name="range"
label="发布时间"
style={{
marginTop: '24px'
}}>
<DatePicker.RangePicker
format="YYYY-MM-DD "
onChange={value => {
dateOnChange(value)
}}
/>
</Form.Item>
也就是这个,onChange事件是在当前内容发生变化的时候的回调。我顺手把选出来的value值传了进去,format是年月日这种。也就是说只显示到日 (不过他的数据自己还是带时分秒的需要自己处理)
dateOnChange(value)现在去找这个函数
//日期選擇
const dateOnChange = async time => {
console.log('time', time)
if (time === null) {
setSearchDateStart(2022 - 1 - 1)
setSearchDateEnd(2122 - 1 - 1)
const { data } = await getNotice(state)
setDataSource(data)
} else {
// 設置選擇的開始時期
setSearchDateStart(dayjs(time[0]._d).format('YYYY-MM-DD'))
// 設置選擇的結束時期
setSearchDateEnd(dayjs(time[1]._d).format('YYYY-MM-DD'))
}
}
time就是value的形参
log了一下time,打印出来了的是两个参数
time (2) [Moment, Moment]
在一番观察之后,form中输入的时间是长这样的
Moment
_d: Wed Jun 29 2022 10:10:05 GMT+0800 (中国标准时间) {}
_isAMomentObject: true
_isUTC: false
_isValid: true
_locale: Locale {_calendar: {…}, _longDateFormat: {…}, _invalidDate: 'Invalid date', _dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/, ordinal: ƒ, …}
_pf: {empty: false, unusedTokens: Array(0), unusedInput: Array(0), overflow: -2, charsLeftOver: 0, …}
[[Prototype]]: Object
为什么还有个if判断呢,因为当点击清除按钮之后,表单时间值为null这个时候只需要把所有数据展示出来就行
time : null
反正现在可以先不看他
看看else里面的
else {
// 設置選擇的開始時期
setSearchDateStart(dayjs(time[0]._d).format('YYYY-MM-DD'))
// 設置選擇的結束時期
setSearchDateEnd(dayjs(time[1]._d).format('YYYY-MM-DD'))
}
起始时间和结束时间都有了。格式为'YYYY-MM-DD',
现在我来介绍一下查询按钮
<Button type="primary" onClick={() => getNoticeData()}>
查询
</Button>
getNoticeData()这个方法本来做的事情,就是去更新table数据和调取数据接口的
现在getNoticeData()更改为这样
// form數據更新
const getNoticeData = useCallback(async () => {
const { data } = await getNotice(state)
setDataSource(data)
if (!(searchDateStart === 2022 - 1 - 1 && searchDateEnd === 2122 - 1 - 1)) {
dataChange(data)
}
}, [state, searchDateStart, searchDateEnd, form])
依赖项加上了起始时间和结束时间,只要他们两个有一个更新,那这个函数就重新加载而当时间选择框数值更改的时候,又调用上面的设置起止时间的函数。就可以基本实现同步了
看下里面的逻辑
const { data } = await getNotice(state)
setDataSource(data)
这两句是原本的内容,实现的功能就是设置了table数据,数据的来源是后台调来的
if (!(searchDateStart === 2022 - 1 - 1 && searchDateEnd === 2122 - 1 - 1)) {
dataChange(data)
}
这一句才是我为了这次的任务更改的。
判断了起止值,是否不是原来的值。只要不是了,那必然是用户更改了。那就调用dataChange函数
关键的筛选部分来了
// 日期筛选
const dataChange = dataChange => {
console.log('dataChange', dataChange)
dataChange.data.map((item, index) => {
if (dayjs(dayjs(item.publish_time * 1000).format('YYYY-MM-DD')).isBetween(searchDateStart, searchDateEnd, 'day', '[]')) {
console.log('第' + index + '列符合条件' + '此条内容为' + item)
console.log(item)
timeArray.push(item)
}
})
console.log(timeArray)
setDataSource({ msg: '', code: 0, data: timeArray })
console.log(dataSource)
setTimeArray([])
}
参数就是刚刚那个data值,这边换个名字叫dataChange。
这个的作用就是筛选和push进新数组,那个数组的内容就是要保留的内容
打印了一下。
dataChange {msg: '', code: 0, data: Array(5)}code: 0data: (5) [{…}, {…}, {…}, {…}, {…}]msg: ""[[Prototype]]: Object
当时仔细观察了一番,其实就是基础的页面数据。data里面就是我们需要修改的数组
每一个data里面都张这样的
0: {id: 77, publish_time: 1656518400, publish_data: 'hhh', state: 0}
比如第0条就是长这样
可以看见,这里的publish_time是个十位数的时间戳。关于对比时候的细节我弄了很久,试过。全转换成时间戳,结果发现有问题,时间选择器的数据是那种中国标准时间那东西,转成时间戳之后就发现数位为13,但是怎么去加上减去时间都不对。最后放弃了这个方法,在询问了大哥之后,得知了dayjs可以选择区间
于是就和dayjs的插件一起使用。我这边用的插件是between
先引入进来
import isBetween from '../../../node_modules/dayjs/plugin/isBetween'
这个要在dayjs里面好好找路径
再
dayjs.extend(isBetween)
这样就可以使用了。
最后是把两个时间数都变成日期格式,
而这个刚才就弄好了
// 設置選擇的開始時期
setSearchDateStart(dayjs(time[0]._d).format('YYYY-MM-DD'))
// 設置選擇的結束時期
setSearchDateEnd(dayjs(time[1]._d).format('YYYY-MM-DD'))
在回头看看主要的判断逻辑
dataChange.data.map((item, index) => {
if (dayjs(dayjs(item.publish_time * 1000).format('YYYY-MM-DD')).isBetween(searchDateStart, searchDateEnd, 'day', '[]')) {
console.log('第' + index + '列符合条件' + '此条内容为' + item)
console.log(item)
timeArray.push(item)
}
})
isBetween就是dayjs的一个插件api,最后的参数决定了包含与否'[]'就是包含,倒数第二个参数决定了比到哪个日期节点,这边是“day”也就是日了
timeArray是一个自己创建的常量,这里存储的是一个数组,所有的符合条件的数组。
下面在循环结束之后把值赋给新的dataSource在渲染结束之后,再重置TimeArray。以让下次选择时间的时候不至于直接继续新增数组
console.log(timeArray)
setDataSource({ msg: '', code: 0, data: timeArray })
console.log(dataSource)
setTimeArray([])
好啦,setDataSource之后就大功告成了