• 作者:老汪软件技巧
  • 发表时间:2024-10-08 04:00
  • 浏览量:

简单的酒店日程日历展示

在本篇博客中,我将分享如何使用 Vue 3、 Element Plus、 date-fns 创建一个动态日历组件,该组件支持房间预订管理功能。这个组件不仅美观,而且用户友好,能够直观地展示每个房间在不同日期的可用性和预订情况。

项目简览概述

我们构建的这个日历组件具有以下功能:

概览

初始化展示当天所在月的预定情况

可选定日期进行跳转 并高亮与居中选中日期

可以通过按钮跳转上个月与下个月 来查看预定信息

点击预定信息已预定的房间 可切换为可用 再次点击输入用户信息来进行预定

组件结构模板部分

在组件的模板中,我们使用了 Element Plus 的表格组件 (el-table) 来展示房间信息和预订状态。下面是组件的核心结构:


状态管理

我们使用了 Vue 的响应式特性来管理组件状态,包括选定的日期、当前月份的开始日期、天数和表格数据。以下是部分状态定义代码:

const selectedDate = ref(new Date());
const currentMonthStartDate = ref(startOfMonth(selectedDate.value));
const days = ref([]);
const tableData = ref([]);

生成月份天数

通过 generateMonthDays 函数,我们动态生成当前月份的天数,并为每一天设置标签和属性:

const generateMonthDays = () => {
  const daysArray = [];
  const start = startOfMonth(currentMonthStartDate.value);
  const daysInMonth = getDaysInMonth(start);
  for (let i = 0; i < daysInMonth; i++) {
    const date = addDays(start, i);
    daysArray.push({
      label: format(date, 'dd\nEEE', {locale: zhCN}),
      prop: `day${i + 1}`
    });
  }
  return daysArray;
};

更新表格数据

表格数据的更新通过 updateTableData 函数来实现,我们根据选定的月份和房间的预订状态来填充表格数据:

const updateTableData = () => {
  // ...更新逻辑
  const roomData = Array.from({length: 5}, (_, rowIndex) => {
    const row = {roomType: `房间${rowIndex + 1}`};
    // 随机生成房间状态
    return row;
  });
  // 添加剩余房间数的行
  const availableRoomsRow = {roomType: '剩几间房'};
  // ...计算剩余房间数
  tableData.value = [availableRoomsRow, ...roomData];
};

处理用户交互

我们通过事件处理函数如handleCellClick和saveBooking来处理用户的点击和保存操作。这些函数确保用户能够轻松地输入预订信息,并实时更新房间的状态。

// 处理单元格点击事件
const handleCellClick = (row, prop) => {
  if (row.roomType === '剩几间房') return;
  if (row[prop].status === '可用') {
    editingCell.value = {rowProp: row.roomType, dayProp: prop};
    row[prop].customerName = '';
  } else {
    row[prop] = {status: '可用', customerName: ''};
    updateAvailableRooms(prop);
  }
};
// 保存预订信息
const saveBooking = (row, prop) => {
  const customerName = row[prop].customerName.trim();
  if (customerName !== '') {
    row[prop].status = '已预订';
  } else {
    row[prop].status = '可用';
  }
  editingCell.value = {rowProp: null, dayProp: null};
  updateAvailableRooms(prop);
};

优化用户体验

通过scrollToSelectedDate和columnStyle来处理选定日期居中和高亮

const scrollToSelectedDate = (date) => {
  const selectedDay = format(date, 'dd');
  const columnIndex = parseInt(selectedDay) - 1; // 获取列索引,假设日期为 01 - 31 对应索引 0 - 30
  const columnWidth = 150; // 根据你的列宽设置
  const tableWidth = tableRef.value.$el.offsetWidth;
  // 计算居中位置
  const scrollLeft = (columnIndex + 1) * columnWidth - (tableWidth / 2) + (columnWidth / 2);
  // 调用 setScrollLeft 滚动到对应列
  if (tableRef.value) {
    tableRef.value.setScrollLeft(scrollLeft);
  }
};
const columnStyle = ({row, column}) => {
  const dayProp = column.property;
  if (selectedDate.value && isCurrentDay(dayProp)) {
    return {backgroundColor: '#1C86EE', color: '#fff'}; // 高亮的样式
  }
  return {};
};

样式

我们为组件添加了一些基本样式,使其更加美观和易于使用:

.calendar {
  max-width: 100%;
  margin: 0 auto;
}
.controls {
  display: flex;
  justify-content: space-between;
  margin-bottom: 10px;
}
.cell-content {
  cursor: pointer;
  white-space: pre-line;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
}

完整的代码




总结

通过本次分享,我们学习了如何使用 Vue 3 和 Element Plus 创建一个功能完备的动态日历组件。这个组件展示了 Vue 的响应式能力和 Element Plus 组件库的强大功能,能够高效地处理房间预订的需求。希望这篇博客能对你的项目开发有所帮助!