加载中...

el-calendar 日历点击事件获取不到问题


el-calendar 日历点击事件获取不到问题

前言

有一个需求,需要展示一个日历,打开的时候需要获取到日历上面的全部日期拥有的数据,同时还需要对指定的某一天进行数据展示编辑新增,对于这个需求梳理出对应的逻辑:

  1. 日历被通过点击触发的时候,需要调用接口获取到所有的数据
  2. 将获取的数据使用el-calendar的自定义内容,也就是插槽进行展示
  3. 点击某一天的时候,将该内容的数据在日历下发的表单数据进行展示(这里不是本章关注的内容)
  4. 获取到点击的天数的时候,还可以对当日下面的表单数据进行添加修改操作(这里不是本章关注的内容)

bug的产生

在其他接口以及逻辑进行调用和编写的时候一切还是很顺利的,但是在我点击日历的某一天的时候就出现了问题,我慢慢剖析:

  1. 首先来看主要代码内容,其中关于接口调用等方面我进行了省略:
 <el-calendar>
              <div slot="dateCell" slot-scope="{data}">
                <div :class="data.isSelected ? 'is-selected' : ''" @click="allcalendar(data)">
                  <div class="day">
                      {{ data.day.split('-').slice(1).join('-') }} 
                      {{ data.isSelected ? '✔️' : '' }}
                </div>
                  <div class="info" style="display: flex">
                    <div v-for="(i, index) in dateInfo[data.day]" :key="index">{{ i ? '✨' : '' }}</div>
                  </div>
                </div>
              </div>
</el-calendar>

这里稍微介绍下,div class="info"这里面的内容可以不过多说明,里面就是通过展示日历的时候调用接口获取的数据,data.day就是日期,如果返回的数据存在渲染出,这里就是根据自己的情况而定,我们接着来

  1. 我给其中的一个div添加了点击事件@click="allcalendar(data)",将点击到的当天数据传过去,有关el-calendar的自定义内容根据官网的说明提一句:

dateCell scoped slot 参数

date:格代表的日期

data:{ type, isSelected, day},type 表示该日期的所属月份,可选值有 prev-monthcurrent-monthnext-monthisSelected 标明该日期是否被选中;day 是格式化的日期,格式为 yyyy-MM-dd

关于点击事件:

// 选择日期,再获取对应日期的数据
allcalendar(data) {
    this.productDate = data.day
    this.haveDateInfo()
    // 其他省略内容
},

其中this.haveDateInfo()就是我们调用接口的地方,不过多介绍,我们收到传入的天数,这段代码看似来说没有如何问题,从点击事件获取到点击的日期,再赋值到data的数据里面,在调用接口来对点击的日期进行添加修改等操作

  1. 但是问题却出现了:日历出现的时候获取数据和通过自定义内容将数据进行展示,到这里还没有问题,当鼠标点击切换到其他日期的时候,会有概率出现日期赋值不了,这样一来,我们就获取不到点击的日期当日的数据内容,也就不能通过接口获取我们要的数据内容

解决思路

出现这种问题,数组赋值不过去,可能会是异步问题,因为针对element-ui里面的el-calendar内容也没有如何事件,于是修改点击事件的代码,会不会是因为请求的问题导致的,并添加上加载动画:

async allcalendar(data) {
    this.productDate = data.day
      const loading = this.$loading({
        lock: true, 
        text: 'Loading',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      })
      try {
        await this.haveDateInfo()
      } catch (error) {
        console.log(error)
      }
      loading.close()
    },

通过使用这种方法,问题依旧没有解决,加载动画和使用vue-devtools来查看也是没有成功的,只有能看到记载动画才会被赋值

一筹莫展的时候,看到el-calendar是可以使用v-model可以绑定的,这样一来就可以检测到变化,于是修改代码,使用绑定加监听的方法

解决代码

完善代码部分:

对之前的内容稍作简化

<el-calendar v-model="calenderDate">
    <div slot="dateCell" slot-scope="{data}">
       <div :class="data.isSelected ? 'is-selected' : ''">
          <div class="day">
             {{ data.day.split('-').slice(1).join('-') }} 
             {{ data.isSelected ? '✔️' : '' }}
          </div>
       </div>
    </div>
</el-calendar>

data部分填入calenderDate:''即可

watch:{
    calenderDate(newVal, oldVal) {
       // 格式化 因为绑定的数组不是我们想用的,这里以2022-22-22这种格式作为演示
      this.calenderDate = this.formatDate(newVal)
       // 这里就是我们处理数据,调用接口的位置
      this.allcalendar()
    }
}
async allcalendar() {
      this.productDate = this.calenderDate
      const loading = this.$loading({
        lock: true, //加上这个 页面点击日历的时候会莫名其妙抖动一下 因为我界面上有滚动条,所以我注释了
        text: 'Loading',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      })
      try {
        // 这里调用接口肯定是需要点击的日期的,书写自己的处理逻辑即可
        await this.haveDateInfo()
      } catch (error) {
        console.log(error)
      }
      loading.close()
    },

有关这里使用的格式化也一并作为展示:

// 格式化日期函数
    formatDate(date) {
      const value = new Date(date)
      const year = value.getFullYear()
      const month = (value.getMonth() + 1).toString().padStart(2, '0')
      const day = value.getDate().toString().padStart(2, '0')
      return `${year}-${month}-${day}`
    }

文章作者:
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 !