日历的搞搞

发布时间:2024年01月17日

不用组件:

<template>
  <div class="app-container">
    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true">
      <el-form-item label="年份" prop="holidayYear">
        <el-date-picker
          v-model="queryParams.holidayYear"
          type="year"
          :clearable="false"
          placeholder="选择年"
        >
        </el-date-picker>
      </el-form-item>
      <el-form-item>
        <el-button
          type="primary"
          icon="el-icon-search"
          size="mini"
          @click="handleQuery"
          >搜索</el-button
        >
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
          >重置</el-button
        >
      </el-form-item>
    </el-form>
    <el-row>
      <div
        v-for="(cal, index) in defaultCals"
        @click="handleUpdateHoliday(cal)"
        :key="index"
      >
        <el-col :span="6">
          <el-calendar :value="cal" class="holiday">
            <template slot="dateCell" slot-scope="{ date, data }">
              <div
                class="holiday-cell"
                v-show="data.type === 'current-month'"
                :id="cal.getMonth() + '-' + data.day"
              >
                {{ data.day.split("-")[2] }}
              </div>
            </template>
          </el-calendar>
        </el-col>
      </div>
    </el-row>

    <el-dialog title="节假日设置" :visible.sync="show" width="40%">
      <el-calendar :value="currentMonth" class="select-month">
        <!-- 这里使用的是 2.5 slot 语法,对于新项目请使用 2.6 slot 语法-->
        <template slot="dateCell" slot-scope="{ date, data }">
          <div
            class="holiday-cell"
            v-show="data.type === 'current-month'"
            @click="selectDate(date, data)"
          >
            <span>{{ data.day.split("-")[2] }}</span>
            <span :id="data.day">{{ initHolidayDate(data) }}</span>
          </div>
        </template>
      </el-calendar>
      <span slot="footer" class="dialog-footer">
        <el-button @click="show = false">取 消</el-button>
        <el-button type="primary" @click="submitHoliday">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
export default {
  // name: "temp",
  data() {
    return {
      queryParams: {
        holidayYear: new Date(),
      },
      //设置的月份
      defaultCals: [],
      // 全年已选中的日期
      holidayDate: [],
      // 弹框
      show: false,
      // 点击修改的月份
      currentMonth: undefined,
      // 点击月中已选中的日期
      currentDate: [],
    };
  },
  created() {
    //初始化日历
    let nowYear = new Date().getFullYear();
    this.initCalendar(nowYear + 1);
  },
  methods: {
    //初始化日历
    initCalendar(year) {
      this.defaultCals = [
        new Date(year, 0, 1),
        new Date(year, 1, 1),
        new Date(year, 2, 1),
        new Date(year, 3, 1),
        new Date(year, 4, 1),
        new Date(year, 5, 1),
        new Date(year, 6, 1),
        new Date(year, 7, 1),
        new Date(year, 8, 1),
        new Date(year, 9, 1),
        new Date(year, 10, 1),
        new Date(year, 11, 1),
      ];

      //调接口获取
      this.holidayDate = [
        // { day: 2, date: "0-" + year + "-01-02" },
        // { day: 2, date: "1-" + year + "-02-02" },
        // { day: 2, date: "2-" + year + "-03-02" },
        { day: 2, date: "2-2025-03-02" },
        { day: 4, date: "2-2025-03-04" },
        { day: 5, date: "2-2025-03-05" },
        { day: 10, date: "3-2025-04-10" },
      ];
      this.$nextTick(() => {
        let holidayCell = document.getElementsByClassName("holiday-cell");
        for (let i in holidayCell) {
          if (undefined != holidayCell[i].style) {
            holidayCell[i].style.backgroundColor = "#FFFFFF";
          }
        }
        //给已选中的日期加背景色
        for (let i in this.holidayDate) {
          let span = document.getElementById(this.holidayDate[i].date);
          span.style.backgroundColor = "#F56C6C";
        }
      });
    },
    /** 搜索按钮操作 */
    handleQuery() {
      let year = this.queryParams.holidayYear.getFullYear();
      this.initCalendar(year);
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.resetForm("queryForm");
      this.queryParams.holidayYear = new Date();
      this.handleQuery();
    },
    //初始化已选中的日期
    initHolidayDate(data) {
      for (let i in this.currentDate) {
        if (data.day === this.currentDate[i].date) {
          data.isSelected = true;
          return "??";
        }
      }
    },
    //节假日设置
    handleUpdateHoliday(cal) {
      console.log("1");
      this.show = true;
      this.currentMonth = cal;
      //调接口获取
      // this.currentDate = [{ day: 2, date: cal.getFullYear() + "-01-02" }];
      this.currentDate = [{ day: 8, date: "2025-01-08" }];
    },
    selectDate(date, data) {
      console.log("2");
      let day = date.getDate();
      let span = document.getElementById(data.day);
      if (span.innerText) {
        span.innerText = "";
        for (let i in this.currentDate) {
          if (day === this.currentDate[i].day) {
            this.currentDate.splice(i, 1);
          }
        }
      } else {
        span.innerText = "??";
        this.currentDate.push({ day: day, date: data.day });
      }
    },
    //提交
    submitHoliday() {
      console.log(this.currentMonth, this.currentDate);
      this.show = false;
      this.queryParams.holidayYear = this.currentMonth;
      this.handleQuery();
    },
  },
};
</script>

<style>
.holiday .el-calendar__button-group {
  display: none;
}

.select-month .el-calendar__button-group {
  display: none;
}

.holiday .el-calendar-day {
  padding: 1px;
  width: 100%;
  height: 34px;
}

.select-month .el-calendar-day {
  padding: 1px;
  width: 100%;
}

.holiday-cell {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>


用组件:
子组件:

<template>
  <div class="holiday-calendar-with-dialog">
    <!-- 展示日历 -->
    <el-row>
      <div v-for="(cal, index) in defaultCals" :key="index">
        <el-col :span="6">
          <el-calendar :value="cal" class="holiday">
            <template slot="dateCell" slot-scope="{ date, data }">
              <div
                class="holiday-cell"
                v-show="data.type === 'current-month'"
                :id="cal.getMonth() + '-' + data.day"
                @click="handleDateClick(date, data)"
              >
                {{ data.day.split("-")[2] }}
              </div>
            </template>
          </el-calendar>
        </el-col>
      </div>
    </el-row>

    <!-- 节假日设置对话框 -->
    <el-dialog title="节假日设置" :visible.sync="show" width="40%">
      <el-calendar :value="currentMonth" class="select-month">
        <template slot="dateCell" slot-scope="{ date, data }">
          <div
            class="holiday-cell"
            v-show="data.type === 'current-month'"
            @click="selectDate(date, data)"
          >
            <span>{{ data.day.split("-")[2] }}</span>
            <span :id="data.day">{{ initHolidayDate(data) }}</span>
          </div>
        </template>
      </el-calendar>
      <span slot="footer" class="dialog-footer">
        <el-button @click="cancel">取 消</el-button>
        <el-button type="primary" @click="confirm">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
export default {
  props: {
    defaultCals: {
      type: Array,
      required: true,
    },
    holidayDate: {
      type: Array,
      default: () => [],
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    currentDate: {
      type: Array,
      default: () => [],
    },
    initialSelectedDates: {
      type: Array,
      default: () => [],
    },
  },
  data() {
    return {
      show: false,
      currentMonth: undefined,
      selectedDates: [],
    };
  },
  watch: {
    // 当父组件传递的 currentDate 发生变化时,更新 selectedDates
    currentDate: {
      handler(newVal) {
        console.log(newVal);
        
        this.selectedDates = newVal;
      },
      immediate: true,
    },
    // 监听initialSelectedDates的变化,将其赋值给selectedDates
    // initialSelectedDates: {
    //   handler(newVal) {
    //     this.selectedDates = newVal;
    //   },
    //   immediate: true, // 立即执行一次,以便在初始时设置selectedDates
    // },
  },
  created() {
    // 在created生命周期钩子中访问initialSelectedDates
    this.selectedDates = this.initialSelectedDates
    console.log("Initial Selected Dates:", this.initialSelectedDates);
  },
  methods: {
    handleDateClick(date) {
      if (!this.disabled) {
        this.show = true;
        this.currentMonth = date;
      }
    },
    selectDate(date, data) {
      if (!this.disabled) {
        let day = date.getDate();
        let isSelected = this.selectedDates.some((d) => d.day === day);

        if (isSelected) {
          this.selectedDates = this.selectedDates.filter((d) => d.day !== day);
        } else {
          this.selectedDates.push({ day, date: data.day });
        }
      }
    },
    initHolidayDate(data) {
      return this.selectedDates.some((d) => d.date === data.day) ? "??" : "";
    },
    cancel() {
      this.show = false;
      this.selectedDates = [];
    },
    confirm() {
      this.show = false;
      this.$emit("holidaySelected", this.selectedDates);
      this.selectedDates = [];
    },
  },
};
</script>

<style scoped>
.left-wrap /deep/ .el-calendar__button-group {
  display: none;
}

/* 添加一些样式,根据需要自定义样式 */
.holiday .el-calendar__button-group {
  display: none;
}

.select-month .el-calendar__button-group {
  display: none;
}

.holiday .el-calendar-day {
  padding: 1px;
  width: 100%;
  height: 34px;
}

.select-month .el-calendar-day {
  padding: 1px;
  width: 100%;
}

.holiday-cell {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>

父组件

<template>
  <div>
    <!-- 其他内容 -->

    <!-- 使用自定义的日历组件 -->
    <HolidayCalendarWithDialog
      :defaultCals="defaultCals"
      :holidayDate="holidayDate"
      :disabled="isCalendarDisabled"
      :currentDate="currentDate"
      @holidaySelected="handleHolidaySelected"
      :initialSelectedDates="initialSelectedDates"
    />
  </div>
</template>

<script>
import HolidayCalendarWithDialog from "@/components/HolidayCalendarWithDialog.vue";

export default {
  components: {
    HolidayCalendarWithDialog,
  },
  created() {
    //初始化日历
    let nowYear = new Date().getFullYear();
    this.initCalendar(nowYear + 1);
  },
  data() {
    return {
      defaultCals: [], // 你的默认日历数据
      holidayDate: [], // 你的节假日数据
      isCalendarDisabled: false, // 控制日历是否可点击]
      currentDate: [],
      initialSelectedDates: [
        { day: 8, date: "2025-01-08" },
        { day: 8, date: "2025-08-08" },
      ], // 你的当前日期数组,需要传递给子组件
    };
  },
  methods: {
    handleHolidaySelected(selectedDates) {
      // 处理选定的日期逻辑
      console.log("Selected Dates:", selectedDates);
      this.currentDate =selectedDates;
    },
    //初始化日历
    initCalendar(year) {
      this.defaultCals = [
        new Date(year, 0, 1),
        new Date(year, 1, 1),
        new Date(year, 2, 1),
        new Date(year, 3, 1),
        new Date(year, 4, 1),
        new Date(year, 5, 1),
        new Date(year, 6, 1),
        new Date(year, 7, 1),
        new Date(year, 8, 1),
        new Date(year, 9, 1),
        new Date(year, 10, 1),
        new Date(year, 11, 1),
      ];

      //调接口获取
      this.holidayDate = [
        // { day: 2, date: "0-" + year + "-01-02" },
        // { day: 2, date: "1-" + year + "-02-02" },
        // { day: 2, date: "2-" + year + "-03-02" },
        { day: 2, date: "2-2025-03-02" },
        { day: 4, date: "2-2025-03-04" },
        { day: 5, date: "2-2025-03-05" },
        { day: 10, date: "3-2025-04-10" },
      ];
      this.$nextTick(() => {
        let holidayCell = document.getElementsByClassName("holiday-cell");
        for (let i in holidayCell) {
          if (undefined != holidayCell[i].style) {
            holidayCell[i].style.backgroundColor = "#FFFFFF";
          }
        }
        //给已选中的日期加背景色
        for (let i in this.holidayDate) {
          let span = document.getElementById(this.holidayDate[i].date);
          span.style.backgroundColor = "#F56C6C";
        }
      });
    },
  },
};
</script>

文章来源:https://blog.csdn.net/weixin_43828196/article/details/135661487
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。