vue+element ui生成以当月日期时间为表头的table表格

文章讲述了如何使用Vue.js创建一个动态的表格,表头显示当前月份的日期,支持切换月份并根据日期渲染值班情况。通过计算属性获取和处理日期数据,结合后端返回的数据格式,将值班信息展示在表格中。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

最近在写项目的时候遇到了一个新的需求,就是需要生成一个以当前月份日期时间为表头的表格,用来展示这个月的值班情况

表格上方有切换月份的按钮,切换对应的月份,表头要显示对应的月份的日期以及对应月份下面的数据,没有安排值班的日期,用/表示,属于当天的日期时间,将单元格的背景加深

大致的展示效果如下(数据为假数据,只是展示效果使用,具体的以实际为准):
在这里插入图片描述

实现思路

1.最开始的时候想到的是使用日历插件fullCalendar去实现,但是实现出来的效果不是想要的效果,所以就pass掉了
2.然后就在网上看了一系列大家分享的文章,基本的实现思路有了,那么就是解决实现这一块的问题了
3.时间日期为表头这些数据是很好得到的,难点就在于我要怎么实现将后端传过来的对应的日期数据渲染至表格中,还有就是怎么实现对应日期下面的表格操作

实现步骤

  • 先计算出可供切换的年份和月份
  //先得到当前时间的年份和月份
  //在data中定义
    data() {
        return {
            time: {
                year: new Date().getFullYear(),
                month: new Date().getMonth()
            },
        }
    },
    //methods中写上增加年份与月份的方法
    methods:{
        reduceMonth() {
            if (this.time.month > 0) {
                this.time.month = this.time.month - 1
            } else {
                this.time.month = 11
                this.time.year = this.time.year - 1
            }
        },
        addMonth() {
            if (this.time.month < 11) {
                this.time.month = this.time.month + 1
            } else {
                this.time.month = 0
                this.time.year = this.time.year + 1
            }
        },
}
  • 将得到数据与方法写入对应的样式结构中去
            <!-- 月份 -->
            <div class="month-con">
                <i class="el-icon-arrow-left" @click="reduceMonth()" />
                &nbsp;
                <i class="el-icon-arrow-right" @click="addMonth()" />
                <span class="month">{{ month(time.month + 1) }}</span>
                <span>{{ time.year }}</span>
            </div>
  • 切换月份与年份的就完成了,效果如图
    在这里插入图片描述

  • 在计算得到当月的日期数据作为表头数据

//在这里主要使用的是计算属性,利用计算属性得到一个日期时间数组
//还是利用上面步骤中定义好的data数据,这里就不重复了
    computed: {
        // 获取当前月份时间日期
        visibleCalendar: function () {
            // 获取今天的年月日
            const today = new Date()
            today.setHours(0)
            today.setMinutes(0)
            today.setSeconds(0)
            today.setMilliseconds(0)

            const calendarArr = []
            // 获取当前月份第一天
            const currentFirstDay = new Date(this.time.year, this.time.month, 1)
            const d = new Date(this.time.year, this.time.month + 1, 0);
            const currentMonthDay = d.getDate()
            // 获取第一天是周几,注意周日的时候getDay()返回的是0,要做特殊处理
            const weekDay = currentFirstDay.getDay() === 0 ? 7 : currentFirstDay.getDay()
            // 以当前月份的第一天作为第一天
            const startDay = currentFirstDay.getTime()

            // 利用当前月份一共有多少天来显示日历表头
            for (let i = 0; i < currentMonthDay; i++) {
                const date = new Date(startDay + i * 24 * 3600 * 1000)
                // console.log(date,'date');
                let Y = date.getFullYear() + "-";//年
                let M = (date.getMonth() + 1 < 10  ? "0" + (date.getMonth() + 1) : date.getMonth() + 1) + "-";//月
                let D =  (date.getDate() < 10 ? "0" + date.getDate() : date.getDate()) + "";//日
                let nowDate = Y + M + D
                calendarArr.push({
                    date: new Date(startDay + i * 24 * 3600 * 1000),
                    year: date.getFullYear(),
                    month: date.getMonth(),
                    week: this.getweekday(date),
                    day: date.getDate(),
                    keyDate: nowDate,
                })
            }
            return calendarArr
        }
    },
  • 得到表头数据之后生成动态表头
        //在table中生成表头
                <el-table size="mini" border>
                    <el-table-column label="技术员" fixed="left" width="200px">
                        <template slot-scope="{row}">
                            <div>{{ row.name }}</div>
                            <div>手机号: {{ row.tel }}</div>
                            <div>邮箱: {{ row.email }}</div>
                        </template>
                    </el-table-column>
                    <el-table-column :label="item.day + '日' + ',' + item.week" v-for="item in visibleCalendar"
                        :key="item.keyDate" width="100">
                        <template slot-scope="{row}">
                            {{ row.dayData[item.keyDate].event }}
                        </template>
                    </el-table-column>
                </el-table>
  • 渲染完成之后的结构如下,页面多出的部分以滚动条的格式展现
    在这里插入图片描述

  • 到这里,页面的基本样式结构已经差不多得到了,下面就是要进行表格数据的处理,在这里与后端商量好你需要什么样的数据格式,我这边是直接说了我需要这种数据格式

        {
            "name": "zhangsan",
            "tel": "133300008888",
            "email": "zhangsan@163.com",
            "dayData": {
                "2023-05-25": {
                    "startTime": "2023-05-25 09:00:00",
                    "endTime": "2023-05-25 17:59:59",
                    "event": '值班'
                },
                "2023-05-22": {
                    "startTime": "2023-05-22 09:00:00",
                    "endTime": "2023-05-22 17:59:59",
                    "event": '值班'
                },
                "2023-05-21": {
                    "startTime": "2023-05-21 09:00:00",
                    "endTime": "2023-05-21 17:59:59",
                    "event": '值班'
                }
            }
        },
  • 得到数据之后在转换成自己想要的数据格式,在这里我也是在computed计算属性里面进行转换的,方法如下
        //tableData就是得到的接口返回的数据
        //tableOldData就是通过计算属性得到的最终的渲染表格的数据集合
        //visibleCalendar是在上一步骤中得到的日期时间集合
        //keyDate是日期时间集合里面的一个字段,用来作为判断依据的
        tableOldData() {
            const oldData = []
            this.tableData.forEach(item => {
                const newItem = { ...item }
                const dayData = newItem.dayData
                newItem.dayData = {}
                this.visibleCalendar.forEach(date => {
                    let oldDate = date.keyDate
                    if (dayData[oldDate]) {
                        newItem.dayData[oldDate] = dayData[oldDate]
                    } else {
                        newItem.dayData[oldDate] = {}
                    }
                })
                oldData.push(newItem)
            })
            return oldData
        },
  • 再将得到的日期数据渲染至表格中,就可以得到一张以日期时间为表头的动态表格了

总结

在这里主要是介绍如何生成以日期和时间为表头的动态表格,并且能够将数据渲染到表格中去,涉及到表格里面的一些操作,下篇文章进行介绍~

日期时间方法参考博文 教你从零写vue日历组件

### 创建 Vue 2 排班管理表格组件 在 Vue 2 中实现排班管理的表格组件可以利用 `Element UI` 的 `el-table` 组件来完成。通过自定义样式以及逻辑处理,能够满足动态排班的需求。 #### 动态排班的核心思路 为了实现动态排班功能,可以通过以下方式设置单元格样式并绑定事件: - 使用 `cell-style` 方法动态修改单元格背景颜色。 - 结合 `row` 和 `columnIndex` 数据判断特定条件下的单元格状态。 - 借助 JavaScript 计算日期范围,并将其映射到表格结构中。 以下是具体实现: #### 实现代码示例 ```html <template> <div> <!-- 表头 --> <el-table :data="scheduleData" border style="width: 100%"> <el-table-column v-for="(day, index) in daysInMonth" :key="index" :label="'Day ' + (index + 1)"> <template slot-scope="scope"> {{ scope.row[index] }} </template> </el-table-column> </el-table> <!-- 设置 cellStyle --> <el-table :data="tableData" border @cell-click="handleCellClick" :cell-style="cellStyleHandler"> > <el-table-column v-for="(day, idx) in daysInMonth" :key="idx" :label="'Day ' + (idx + 1)" width="150"> <template slot-scope="scope"> {{ scope.row[idx] || '-' }} </template> </el-table-column> </el-table> </div> </template> <script> export default { data() { return { year: new Date().getFullYear(), month: new Date().getMonth() + 1, tableData: [], scheduleData: [], // 存储排班数据 selectedCells: {}, // 已选中的单元格记录 }; }, computed: { daysInMonth() { const date = new Date(this.year, this.month, 0); return date.getDate(); }, }, methods: { handleCellClick(row, column, cell, event) { const rowIndex = row.index; const columnIndex = column.property; if (!this.selectedCells[rowIndex]) { this.$set(this.selectedCells, rowIndex, {}); } this.$set( this.selectedCells[rowIndex], columnIndex, !this.selectedCells[rowIndex][columnIndex] ); }, cellStyleHandler({ row, column, rowIndex, columnIndex }) { let key = `${rowIndex}-${columnIndex}`; if (this.selectedCells[rowIndex]?.[columnIndex]) { return { backgroundColor: '#4CAF50', color: '#fff' }; // 修改已选中单元格的颜色 } return {}; }, }, mounted() { // 初始化表格数据 for (let i = 0; i < 7; i++) { this.tableData.push({ index: i, ...Array.from({ length: this.daysInMonth }, () => null), }); } }, }; </script> ``` #### 关键点解析 1. **计算当月天数** 利用 JavaScript 的 `Date` 对象获取指定年份和月份的总天数[^2]。 2. **动态生成表头** 遍历每一天作为列名显示出来,方便用户查看具体的日期对应关系。 3. **点击事件监听** 当用户单击某个单元格时触发 `@cell-click` 事件,在回调函数中更新该单元格的状态,并存储至 `selectedCells` 对象中以便后续渲染使用。 4. **自定义单元格样式** 定义 `cellStyleHandler` 函数,基于当前行号 (`rowIndex`) 及列号 (`columnIndex`) 来决定是否应用特殊样式[^1]。 --- ###
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值