element-ui组件库中Calendar日历组件使用心得(可能用到的常用方法和如何添加监听)

1,644 阅读1分钟

最近接触到一个需求,做一个值班排班表,拿到低保真之后一直在考虑是如何实现这个排班表,考虑过自己写,也考虑过@fullcalendar/vue插件,经过一些评估之后最终选择了项目本身使用的element-ui组件库中Calendar日历组件,但是在使用过程中发现此组件api少的可怜,连基本的一些点击事件都没透传出来,这样就不太好去实现根据月份查询排班信息,但是作为前端老司机总归是能解决的。

解决方案想过有成功的,也有失败的,我都贴出来,可以看看。

1、方案一:computed子组件的curMonthDatePrefix,然后再用watch监听curMonthDatePrefix,结论:失败,对curMonthDatePrefix的watch没任何反应。

computed: {
	curMonthDatePrefix() {
	  let myCalendar = this.$refs.myCalendar;
	  return myCalendar? myCalendar.curMonthDatePrefix : "" ;
	},
},
watch: {
	curMonthDatePrefix: {
	  immediate: true,
	  handler: function (newval, oldval) {
	    console.log("value", this.value);
	    console.log("testnewval", newval);
	    console.log("testoldval", oldval);
	  },
	},
},

2、方案二:像watch对象中某个属性一样,结论:失败,对curMonthDatePrefix的watch没任何反应。

watch: {
    "$refs.myCalendar.curMonthDatePrefix": {
	      immediate: true,
	      handler: function (newval, oldval) {
	        console.log("value", this.value);
	        console.log("testnewval", newval);
	        console.log("testoldval", oldval);
	      },
    },
 },

3、方案三:使用vm.$watch API,结论:成功。

引用Calendar的组件:

mounted() {
    this.$watch(
	    function () {
	        // 这就像监听一个未被定义的计算属性
	        return this.$refs.myCalendar.curMonthDatePrefix;
	    },
	    function (newVal) {
	        // 可在此事件中添加请求信息之类的方法
	        console.log("curMonthDatePrefix", newVal);
	    },
	    { immediate: true }
    );
 },

4、方案四:使用extends继承Calendar组件,其合并原则和Mixins类似。继承组件myCalendar.vue中添加watch监听curMonthDatePrefix,在监听事件中添加emit,结论:成功。这也是我最终采用的方式,这种方式还可以改写template,以便后期更好地扩展,同时在下面的代码中加了一下可能会用到的方法。

myCalendar.vue:

<script>
import { Calendar } from "element-ui";
export default {
  name: "Calendar",
  extends: Calendar,
  watch: {
    curMonthDatePrefix: {
      immediate: true,
      handler: function () {
        this.$emit("curMonthDatePrefixChange", this.curMonthDatePrefix);
      },
    },
  },
};
</script>

引用myCalendar的组件:

<template>
  <div>
    <my-calendar
      ref="myCalendar"
      v-model="value"
      @curMonthDatePrefixChange="curMonthDatePrefixChangeHandler"
    >
    </my-calendar>
  </div>
</template>
<script>
import myCalendar from "./myCalendar";
import fecha from "element-ui/src/utils/date"; //element-ui中处理时间的工具类
export default {
  name: "Duty",
  components: {
    myCalendar,
  },
  data() {
    return {
      value: new Date(),
      test: "",
    };
  },
  methods: {
    curMonthDatePrefixChangeHandler(curMonthDatePrefix) {
      console.log(curMonthDatePrefix);
      // 可在此事件中添加请求信息之类的方法
      console.log("curMonthDatePrefix", curMonthDatePrefix);
      console.log("getMondayDay", this.getMondayDay(curMonthDatePrefix));
      console.log("getSundayDay", this.getSundayDay(curMonthDatePrefix));
      console.log(
        "getLastSundayDay",
        this.getLastSundayDay(curMonthDatePrefix)
      );
      console.log(
        "getLastDayOfMonth",
        this.getLastDayOfMonth(curMonthDatePrefix)
      );
      console.log(
        "getFirstDayOfMonth",
        this.getFirstDayOfMonth(curMonthDatePrefix)
      );
    },
    /**
     * @description: 获取日历面板上第一个周一
     * @param {*} Month 2022-04
     * @return {*} 第一个周一的日期 2022-03-28
     */
    getMondayDay(Month) {
      let now = new Date(this.getFirstDayOfMonth(Month));
      let day = now.getDay() || 7;
      return fecha.format(
        new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1 - day),
        "yyyy-MM-dd"
      );
    },
    /**
     * @description: 获取某月最后一天后面最近的一个周末
     * @param {*} Month 2022-04
     * @return {*} 某月最后一天后面最近的一个周末 2022-05-01
     */
    getSundayDay(Month) {
      let now = new Date(this.getLastDayOfMonth(Month));
      let day = now.getDay() || 7;
      return fecha.format(
        new Date(now.getFullYear(), now.getMonth(), now.getDate() + 7 - day),
        "yyyy-MM-dd"
      );
    },
    /**
     * @description: 获取日历面板上最后一个周末
     * @param {*} Month 2022-04
     * @return {*} 最后一个周末的日期 2022-05-08
     */
    getLastSundayDay(Month) {
      let monday = new Date(this.getMondayDay(Month));
      let sunday = monday.setDate(monday.getDate() + 41);
      return fecha.format(new Date(sunday), "yyyy-MM-dd");
    },
    /**
     * @description: 获取某月最后一天
     * @param {*} Month 月份 2022-04
     * @return {*} 某月最后一天日期 2022-04-30
     */
    getLastDayOfMonth(Month) {
      let curMonth = Month.split("-");
      let year = curMonth[0];
      let month = curMonth[1];
      return fecha.format(new Date(year, month, 0), "yyyy-MM-dd");
    },
    /**
     * @description: 获取某月第一天
     * @param {*} Month 月份 2022-04
     * @return {*} 某月第一天日期 2022-04-01
     */
    getFirstDayOfMonth(Month) {
      let curMonth = Month.split("-");
      let year = curMonth[0];
      let month = curMonth[1];
      return fecha.format(new Date(year, month - 1).setDate(1), "yyyy-MM-dd");
    },
  },
};
</script>

Time!