更简单的方法实现el-calendar日历组件中点击上个月、今天、下个月按钮时的点击事件

14 篇文章 0 订阅
7 篇文章 0 订阅

在这里插入图片描述

网上查el-calendar相关的按钮点击事件文章,清一色都是在mounted挂载阶段通过document.querySelector绑定类名添加点击事件。

我想说为啥要弄得这么麻烦?el-calendar组件标签中v-model绑定了一个Date/string/number的时间值,无论点击上述哪个按钮,该值都是会改变的。
而我们想要实现的是当该时间值改变时(例如变成上个月或下个月或其他时间变回今天)执行某个事件,那直接用watch来监听该值来实现逻辑不就更方便且简单了么


放一下我这边的代码:
el-calendar组件标签,v-model绑定的变量命名为calendarDate:

      <el-calendar v-model="calendarDate">
        <template slot="dateCell" slot-scope="{ date, data }">
          <p :class="data.isSelected ? 'is-selected' : ''">
            {{ data.day.split("-").slice(1).join("-") }}
            {{ data.isSelected ? "✔️" : "" }}
          </p>
          <el-input
            v-if="data.type == 'current-month'"
            :disabled="timeOptions(date)"
            v-model="calendarData[date.getDate() - 1]"
            step="0.01"
            type="number"
            size="mini"
            :min="0"
          >
          </el-input>
        </template>
      </el-calendar>

js代码:
(这里用到了momentjs,一个非常方便的时间处理类库,建议使用,官方文档传送门:Moment.js

let moment = require("moment");

  data() {
    return {
      // 让el-calendar绑定一个Date型的值,初始为当前时间
      calendarDate: new Date(),
      calendarData: [0],
    };
  },

  watch: {
    // 用watch监听calendarDate
    // 1. 我自己项目中用到的较为简单的逻辑:
    // 即不管点击了上月还是下月,只要时间改变,就执行函数initFormData,调用接口,将请求到的新数据重新渲染在el-calendar组件的内容上
    calendarDate(val, oldVal) {
      if (
        val &&
        moment(val).format("YYYY-MM") != moment(oldVal).format("YYYY-MM")
      ) {
        this.initFormData(val);
      }
    },

	// 2. 更严谨的写法,直接复制粘贴代码的朋友记得把上方的1.删掉再使用
	calendarDate(val, oldVal) {
      if (
        val &&
        moment(val).format("YYYY-MM-DD") == moment().format("YYYY-MM-DD")
      ) {
        console.log("点击了‘今天’按钮");
      } else if (
        val &&
        moment(val).toDate() < moment(oldVal).startOf("month").toDate()
      ) {
        console.log("点击了‘上个月’按钮");
      } else if (
        val &&
        moment(val).toDate() > moment(oldVal).endOf("month").toDate()
      ) {
        console.log("点击了‘下个月’按钮");
      } else {
        console.log("点击了" + moment(val).format("YYYY-MM") + "的按钮");
      }
    },
  },

实操效果:

在这里插入图片描述
不过这种实现方式有个小bug:当天是某个月的1日时,通过点击“上个月”和“下个月”按钮回到当月,就会执行点击“今日”的逻辑事件。这个就根据各位项目中的用法自行优化了。


直接绑定点击事件

使用最开始说的那种在mounted里绑定点击事件的方法,可以避免上述bug,在这里也一起贴上来,可自行择优使用:

<script>
export default {
  name: "Calendar",
  data() {
    return {
      calendarDate: new Date(),
    };
  },
  components: {},
  mounted() {
    this.$nextTick(() => {
      // 点击前一个月
      let prevBtn = document.querySelector(
        ".el-calendar__button-group .el-button-group>button:nth-child(1)"
      );
      prevBtn.addEventListener("click", () => {
        this.judgeDate(this.calendarDate);
      });
      let dayBtn = document.querySelector(
        ".el-calendar__button-group .el-button-group>button:nth-child(2)"
      );
      dayBtn.addEventListener("click", () => {
        this.judgeDate(this.calendarDate);
      });
      let nextBtn = document.querySelector(
        ".el-calendar__button-group .el-button-group>button:nth-child(3)"
      );
      nextBtn.addEventListener("click", () => {
        this.judgeDate(this.calendarDate);
      });
    });
  },
  methods: {
    // 判断时间
    judgeDate(dateVal) {
		console.log(dateVal);
    },
  },
};
</script>

更多日历组件的项目应用可详见我的下一篇文章,例如给每一天加input输入框、超过当天时间和跨一个月前的时间禁用输入框等等:
在这里插入图片描述

感谢观看,THX~

  • 16
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值