elementPlus之日历扩展功能

在这里做个记录,感觉用得还挺多的

功能有如下:

  • 切换月份按钮对应日历视图和中间日期都要变
  • 选择日期日历视图要变
  • 点击日历视图中的不属于当前选中月份的日期即可触发日历视图变化以及中间日期也要变

代码如下:

javascript 复制代码
<template>
  <div class="calendar-test">
      <div class="calendar-test-content">
        <el-calendar
          ref="calendar"
          :model-value="selectedDate"
          @update:model-value="handleDateChange"
        >
          <template #header="{ date }">
            <div class="header-operate" style="width: 100%">

              <div class="calendar-title">
                <div class="calendar-buttom" @click="onArrowEvent('prev-month')">
                  <el-icon><ArrowLeft /></el-icon>
                </div>
                <div class="date-text">
                  <el-date-picker
                    v-model="calendarParam.selectedMonth"
                    type="month"
                    :placeholder="calendarParam.selectedMonth"
                    popper-class="month-picker"
                    format="YYYY-MM"
                    value-format="YYYY-MM"
                    :clearable="false"
                    @change="handleMonthChange"
                  />
                </div>
                <div class="calendar-buttom" @click="onArrowEvent('next-month')">
                  <el-icon><ArrowRight /></el-icon>
                </div>
              </div>
            </div>
          </template>
          <template #date-cell="{ data }">
            <div class="date-cell" style="height: 100%">
              <div class="day">{{ data.day.split("-").slice(2)[0] }}</div>
              <div class="day-content">
                <span class="day-title">这是内容</span>
              </div>
            </div>
          </template>
        </el-calendar>
      </div>
    </div>
</template>
<script setup>
import { reactive, ref, watch, onMounted, nextTick } from "vue";
import { useRouter, useRoute } from "vue-router";
import dayjs from "dayjs";
import { ArrowLeft,ArrowRight} from "@element-plus/icons-vue";

const router = useRouter();
const route = useRoute();

// 获取日历数据的查询参数
const calendarParam = reactive({
  selectedMonth: ref(dayjs().format("YYYY-MM")), // 设置默认值为当前月份
});

const calendarData = ref([]);
const getCalendarData = async () => {
  const result = await xxxxxrequest({ ...calendarParam });
  if (result.code == 200) {
    calendarData.value = result.data;
  }
};


const calendar = ref(null);
const selectedDate = ref(new Date()); // 初始日期

// 处理日期选择变化
const handleMonthChange = (val) => {
  if (!calendar.value) return;
  getCalendarData();
  // 更新日历视图
  selectedDate.value = new Date(val); // 根据选择的月份更新日历视图
};
// 处理点击选中日历中日期变化
const handleDateChange = (date) => {
  selectedDate.value = date;
  // 更新 calendarParam.selectedMonth为选中日期所在月份
  calendarParam.selectedMonth= dayjs(date).format("YYYY-MM");
  getCalendarData();
};
// 处理箭头点击事件
const onArrowEvent = (val) => {
  if (!calendar.value) return;
  const currentDate = dayjs(calendarParam.selectedMonth);
  // 根据点击的箭头更新月份
  let newDate;
  if (val === "prev-month") {
    newDate = currentDate.subtract(1, "month");
  } else {
    newDate = currentDate.add(1, "month");
  }

  // 更新 calendarParam.selectedMonth
  calendarParam.selectedMonth= newDate.format("YYYY-MM");
  // 更新日历视图
  calendar.value.selectDate(val);
  // 直接设置日历的日期
  calendar.value.date = newDate.toDate();
  // getCalendarData()
};

onMounted(() => {});
</script>
<style lang="scss" scoped>
.calendar-test {
  :deep(.el-calendar-table) {
    border-spacing: 10px;
    border-collapse: separate;
  }
  :deep(.el-calendar-table th) {
    padding: 0;
    height: 31px;
    background: #eef8ff;
    border-radius: 6px;
  }
  :deep(.el-calendar-table td) {
    border: 1px solid #d9eaf7;
    border-radius: 6px;
    // padding: 10px;
    transition: background-color 0.2s ease;
  }
  :deep(.el-calendar-day:hover) {
    background: none;
  }

  :deep(.current:hover) {
    background: #eef8ff;
    cursor: pointer;
  }
  :deep(.el-calendar-table td.is-selected) {
    border: 1px solid #0080ff;
  }
  :deep(.current .day) {
    color: #666;
  }
  :deep(.current .day-title) {
    color: rgba(90, 91, 97, 0.8);
  }
  :deep(.current .day-num) {
    color: var(--el-color-primary);
  }
}

.calendar-test {
    padding-top: 40px;
    padding-bottom: 60px;
    background-color: #f4f6f9;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    .calendar-test-content {
      width: 1200px;
    }
    .header-operate {
      display: flex;
      justify-content: space-between;
      align-items: center;
      .calendar-title {
        display: flex;
        align-items: center;
        justify-content: space-between;
      }
      .calendar-buttom {
        background-color: #0251d9;
        border-radius: 4px 4px 4px 4px;
        color: #fff;
        width: 30px;
        height: 30px;
        display: flex;
        justify-content: center;
        align-items: center;
        cursor: pointer;
      }
    }
    .date-cell {
      display: flex;
      flex-direction: column;
      justify-content: space-around;
      .day {
        font-size: 18px;
        font-weight: bold;
      }
      .day-content {
        display: flex;
        justify-content: space-between;
        align-items: center;
        .day-title {
          font-size: 12px;
        }
        .day-num {
          font-size: 24px;
          font-weight: bold;
        }
      }
    }
  }
.date-text {
  margin: 0 12px;

  :deep(.el-input) {
    .el-input__wrapper {
      box-shadow: none !important;
      padding: 0;
      background: none;
    }

    .el-input__inner {
      color: #030411;
      font-size: 18px;
      font-weight: 700;
      text-align: center;
    }

    // 隐藏日历图标
    .el-input__suffix,
    .el-input__prefix {
      display: none;
    }
  }
}
</style>
相关推荐
熊出没26 分钟前
Vue前端导出页面为PDF文件
前端·vue.js·pdf
VOLUN26 分钟前
Vue3项目中优雅封装API基础接口:getBaseApi设计解析
前端·vue.js·api
此乃大忽悠31 分钟前
XSS(ctfshow)
javascript·web安全·xss·ctfshow
江城开朗的豌豆2 小时前
Vuex数据突然消失?六招教你轻松找回来!
前端·javascript·vue.js
好奇心笔记2 小时前
ai写代码随机拉大的,所以我准备给AI出一个设计规范
前端·javascript
江城开朗的豌豆2 小时前
Vue状态管理进阶:数据到底是怎么"跑"的?
前端·javascript·vue.js
我想说一句2 小时前
React待办事项开发记:Hook魔法与组件间的悄悄话
前端·javascript·前端框架
真夜2 小时前
CommonJS与ESM
前端·javascript
G等你下课2 小时前
从点击到执行:如何优雅地控制高频事件触发频率
前端·javascript·面试
Jackson_Mseven2 小时前
面试官:说说 startTransition 和 useDeferredValue?我:我用它一行代码救了首页!
前端·javascript·面试