vant:Calendar组件踩坑

2,448 阅读1分钟

需求及解决方案

一、实现在日期下面添加小点,如下:

image.png 组件中有提供formatter方法,可以给每个day数据结构添加样式: image.png

<van-calendar ... :formatter="formatter" />
<script>
    // 根据接口返回的数据,判断该日期是否在需要下标点的日期,如果需要,责添加对应的类名
    formatter(day){
    // 将date对象转换为字符串
        let dayStr = `${day.date.getFullYear()}-${day.date.getMonth() + 1}-${day.date.getDate()}`
        // 判断当前接口返回的数据中是否包含该字符串,有则添加类名
        this.dateArr.includes(dayStr)?day.className = 'spot':'';
    }
    //spot类是一个伪元素,给日历下面添加‘小点’
</script>

二、在上述中,假设后端返回的含‘小点’的数据是按月返回的,每当月份切换时,进行请求,如何实现?

image.png 组件提供了month-show方法,月份进入可视区域时,触发。

最初的想法是:每次进入可视区域后,在触发的函数中,先清空上次保存的数据,再进行下一月份数据的请求

但是由于该函数,在下一个月份刚展示一点点时,就会触发,此时还没有离开上一个月份,数据就被清空,导致页面效果很差。

但是,后续测试发现,这个函数有一个特点,每个月份在进入可视区域后,都只会在第一次进入可视区域时触发一次

所以:在不同月份进入可视区域时,不必清空上次保存的数据,直接push到数组中,当calendar渲染day对象时,根据day对象是否在该数组中,添加类名。

<van-calendar ... @month-show="getDate" />
// 请求后端返回的含‘小点’的日期,放在spotArr中
let spotArr = []
// 每次月份切换时,都会触发
getDate(date) {
    ajax(...).then((date)=>{
        spotArr.push(date)
    });
},

// 配合上述day的formatter方法,实现月份切换时,请求数据,并将‘小点’渲染在页面上。

三、根据外部选中的日期,修改calendar组件内部选中的日期,截图如下:

image.png vant组件中有提供reset方法,参数为date对象,通过ref获取到组件对象,重置选中日期:

// dateStr为2022-11-01
tabClick(dateStr){
    // 转换为date对象
    let dateObj = new Date(Date.parse(item.date.replace(/-/g, '/')));
    this.$refs.calendar.reset(dateObj);
}

四、一些可能用到的基础知识补充

date对象<==>字符串

① 将2022-09-11转换为date对象

// 将2022-09-11转换为date对象
new Date(Date.parse(res.time.replace(/-/g, '/')));
// date对象转换为字符串:格式xxxx/xx/xx,先用正则替换,输出为2022/09/11
time.replace(/-/g, '/')
// 使用Date.parse方法,转换为时间戳
Date.parse(res.time.replace(/-/g, '/'))
// 最后使用new Date转换为Date对象
new Date(Date.parse(res.time.replace(/-/g, '/')))

Date.parse实现将日期转换为时间戳,参数如下:
火狐浏览器不支持转换日期格式为:xxxx-xx-xx,所有浏览器都支持:xxxx/xx/xx,所以上面的代码做了转换。

image.png

② 将当前时间转换为xxxx-xx-xx格式

// Date对象提供多种方法,获取年月日时间等,使用字符串拼接即可
// 将当前时间转换为xxxx-xx-xx格式
function getDate() {
    var now = new Date(),
        y = now.getFullYear(),
        m = now.getMonth() + 1,
        d = now.getDate();
    return y + "-" + (m < 10 ? "0" + m : m) + "-" + (d < 10 ? "0" + d : d) + " " + now.toTimeString().substr(0, 8);
}