记录一下el-calendar在不同时区下会出现的Bug

由于项目的需要,用到了日历组件,在北京时区下一切都很正常,直到切换时区后(下图案例为UTC-12:00),这个组件就出现了一些问题

该问题的原因:new Date() 会获取根据你电脑设置的时区来获取相应的时间

由于项目需要的解决方式为:将此组件设置为以北京时区为准。

但是我在网上搜索了一堆相关的解决方式,都不能够解决我的问题,所以我自己进行了一些细微的更改(如果你有更好的方式,欢迎指导)虽然这种方式很笨,但是有效

解决方式:

注意:千万要使用 v-model 来绑定变量,否则就会出现上图的问题

<el-calendar class="calendar" ref="calendar">
    <template slot="dateCell" slot-scope="{ date, data }">
        <div :class="{'now-date':nowBJDate===data.day}" :id="data.day">
            {{ data.day.split("-").slice(2).join("-") }}
        </div>
    </template>
</el-calendar>

首先介绍一下 slot-scope 中的两个字段里的值:

  • date:根据你的时区获取到的日期,如果系统的时区与你想要的时区不同,就不要用这个date了
  • data:{ type, isSelected, day},type 表示该日期的所属月份,可选值有 prev-month,current-month,next-month;isSelected 标明该日期是否被选中;day 是格式化的日期,格式为 yyyy-MM-dd

第一步:使用 id 绑定上当前日期的字符串,主要用于快捷切换月份按钮(上个月-今天-下个月)使用

 

并给日期的这个div绑定上点击事件(因为没有v-model)所以需要以这种方式来监听选中日期

第二步:data中定义一个变量:nowBJDate;

在created中获取到当前的北京时间:new Date().toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' })

将这个北京时间格式化为:yyyy-MM-dd 后赋值给 nowBJDate

created(){
    // 是将传入日期格式化为指定格式的方法
    this.nowBJDate = formatTime(new Date().toLocaleString('en-US', { timeZone: 'Asia/Shanghai' }),'Y-M-D')
    this.changeNowBJDateFn() //调用定期刷新当前北京时间的方法
},
beforeDestroy(){
    clearTimeout(this.changeBJDateTimer)
},
methods: {
    changeNowBJDateFn(){
      let bjDate1 = formatTime(new Date().toLocaleString('en-US', { timeZone: 'Asia/Shanghai' }),'Y-M-D h:m:s')
      let bjDate2 =  formatTime(new Date().toLocaleString('en-US', { timeZone: 'Asia/Shanghai' }),'Y-M-D 00:00:00')
      let Countdown = +new Date(bjDate2) - +new Date(bjDate1) + 86401000 //获取当前北京时间到第二天00:00:01的时间差
      this.changeBJDateTimer = setTimeout(()=>{
        this.nowBJDate = formatTime(new Date().toLocaleString('en-US', { timeZone: 'Asia/Shanghai' }),'Y-M-D')
        this.changeNowBJDateFn()
      },Countdown)
    },
}

 第三步:在mounted生命周期中给快捷切换月份的按钮绑定点击事件,代码如下

let calendarEl = document.getElementsByClassName('el-calendar')[0];
let tdElArr =  Array.from(calendarEl.getElementsByTagName('td'));//获取所有日期元素
tdElArr.forEach(item=>{
    item.onclick = ()=>{
        // 添加点击事件 item.children[0].children[0].id 指向 元素中的日期id
        this.changeDate(item.children[0].children[0].id)
    }
})
let btnBoxEl = document.getElementsByClassName('el-calendar__button-group')[0];
let btnEl = Array.from(btnBoxEl.getElementsByClassName('el-button'));//获取到三个按钮组成的数组
btnEl.forEach((item,index)=>{
    // 遍历给每个按钮添加点击事件
    item.onclick = (e)=>{
        if(index==1){//index==1 的是回到今天,点击后直接调用pickDay方法指向当前北京时间
            this.$refs.calendar.pickDay(this.nowBJDate);//调用日历插件中的选中日期方法
        }
        this.$nextTick(()=>{
            // 这一步是获取此时被选中的日期的id,也就是格式化后的日期
            let selectEl = calendarEl.getElementsByClassName('is-selected')[1]
            if(selectEl){
              //调用改变日期后获取数据的接口
              this.changeSelectDay(selectEl.id)
            }
        })
    }
})
// 这一步是初始化时的数据
this.changeSelectDay(this.nowBJDate)
// 给当前北京日期增加选中效果
this.$refs.calendar.pickDay(this.nowBJDate)

第四步:css样式调整

// 将element默认选中的今日日期蓝色字体去除
/deep/.el-calendar-table td.is-today{
    color: #333 !important;
}
.now-date{
  // 此处添加你自己的今日日期样式即可
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值