效果图
功能:
(1)动态生成课程节数、时间周期
(2)遇到学科相等的可进行行合并、已解决合并后表格变形问题
使用到的插件:
(1)moment
Timetable.js
let weekCourse = [ { week: 0, courses: [ { index: 1, startTime: "08:00", //开始时间 endTime: "09:30", //结束时间 subject: "高等数学", //学科 major: "计算机科学与技术", //专业 class: "1702班", //班级 }, { index: 3, startTime: "08:00", //开始时间 endTime: "09:30", //结束时间 subject: "语文", //学科 major: "计算机科学与技术", //专业 class: "1702班", //班级 }, ], }, { week: 1, courses: [ { index: 1, startTime: "08:00", //开始时间 endTime: "09:30", //结束时间 subject: "物理", //学科 major: "计算机科学与技术", //专业 class: "1702班", //班级 }, { index: 2, startTime: "08:00", //开始时间 endTime: "09:30", //结束时间 subject: "高等数学", //学科 major: "计算机科学与技术", //专业 class: "1702班", //班级 }, { index: 3, startTime: "08:00", //开始时间 endTime: "09:30", //结束时间 subject: "语文", //学科 major: "计算机科学与技术", //专业 class: "1702班", //班级 }, { index: 4, startTime: "08:00", //开始时间 endTime: "09:30", //结束时间 subject: "大学英语", //学科 major: "计算机科学与技术", //专业 class: "1702班", //班级 }, { index: 5, startTime: "08:00", //开始时间 endTime: "09:30", //结束时间 subject: "Vue", //学科 major: "计算机科学与技术", //专业 class: "1702班", //班级 }, { index: 6, startTime: "08:00", //开始时间 endTime: "09:30", //结束时间 subject: "Vue", //学科 major: "计算机科学与技术", //专业 class: "1702班", //班级 }, { index: 7, startTime: "08:00", //开始时间 endTime: "09:30", //结束时间 subject: "Java", //学科 major: "计算机科学与技术", //专业 class: "1702班", //班级 }, { index: 8, startTime: "08:00", //开始时间 endTime: "09:30", //结束时间 subject: "数据结构与算法", //学科 major: "计算机科学与技术", //专业 class: "1702班", //班级 }, { index: 9, startTime: "08:00", //开始时间 endTime: "09:30", //结束时间 subject: "React", //学科 major: "计算机科学与技术", //专业 class: "1702班", //班级 }, { index: 10, startTime: "09:30", //开始时间 endTime: "09:30", //结束时间 subject: "Php", //学科 major: "计算机科学与技术", //专业 class: "1702班", //班级 }, { index: 11, startTime: "08:00", //开始时间 endTime: "09:30", //结束时间 subject: "Php", //学科 major: "计算机科学与技术", //专业 class: "1702班", //班级 }, ], }, { week: 2, courses: [ { index: 5, startTime: "08:00", //开始时间 endTime: "09:30", //结束时间 subject: "物理", //学科 major: "计算机科学与技术", //专业 class: "1702班", //班级 }, { index: 8, startTime: "08:00", //开始时间 endTime: "09:30", //结束时间 subject: "语文", //学科 major: "计算机科学与技术", //专业 class: "1702班", //班级 }, ] }, { week: 3, courses: [ { index: 1, startTime: "08:00", //开始时间 endTime: "09:30", //结束时间 subject: "物理", //学科 major: "计算机科学与技术", //专业 class: "1702班", //班级 }, { index: 2, startTime: "08:00", //开始时间 endTime: "09:30", //结束时间 subject: "物理", //学科 major: "计算机科学与技术", //专业 class: "1702班", //班级 }, { index: 3, startTime: "08:00", //开始时间 endTime: "09:30", //结束时间 subject: "语文", //学科 major: "计算机科学与技术", //专业 class: "1702班", //班级 }, ], }, { week: 4, courses: [ { index: 1, startTime: "08:00", //开始时间 endTime: "09:30", //结束时间 subject: "物理", //学科 major: "计算机科学与技术", //专业 class: "1702班", //班级 }, { index: 3, startTime: "08:00", //开始时间 endTime: "09:30", //结束时间 subject: "语文", //学科 major: "计算机科学与技术", //专业 class: "1702班", //班级 }, ], }, { week: 5, courses: [ { index: 4, startTime: "08:00", //开始时间 endTime: "09:30", //结束时间 subject: "物理", //学科 major: "计算机科学与技术", //专业 class: "1702班", //班级 }, { index: 3, startTime: "08:00", //开始时间 endTime: "09:30", //结束时间 subject: "语文", //学科 major: "计算机科学与技术", //专业 class: "1702班", //班级 }, ], }, { week: 6, courses: [ { index: 2, startTime: "08:00", //开始时间 endTime: "09:30", //结束时间 subject: "物理", //学科 major: "计算机科学与技术", //专业 class: "1702班", //班级 }, { index: 11, startTime: "08:00", //开始时间 endTime: "09:30", //结束时间 subject: "语文", //学科 major: "计算机科学与技术", //专业 class: "1702班", //班级 }, ], }, ]//课程详细信息 let colorList = [ "#4BBDEE", "#E86EEB", "#4BBDEE", "#13DAC2", "#7464FB", "#F18141", "#57C946", "#E8BE2A", "#508AFA", ] export { weekCourse, colorList }
复制
Timetable.vue
<template> <div class="timetable w100 h100"> <div class="time-b w100"> <div class="time-detail">{{ startTime }} - {{ endTime }}</div> <div class="time-controller"> <el-button-group> <el-button type="primary" icon="el-icon-arrow-left" @click="changeCount(1), getWeek(count)" ></el-button> <el-button round class="date-btn">本周</el-button> <el-button type="primary" icon="el-icon-arrow-right" @click="changeCount(-1), getWeek(count)" ></el-button> </el-button-group> </div> </div> <div class="timetable-b w100"> <table class="timetable-content w100"> <thead> <tr> <th></th> <!-- <th>周一</th> <th>周二</th> <th>周三</th> <th>周四</th> <th>周五</th> <th>周六</th> <th>周日</th> --> <th v-for="(item1, index1) in weeks" :key="index1"> {{ "周" + numberToChinease(item1 + 1, "week") }} </th> </tr> </thead> <tbody> <tr v-for="(item2, index2) in maxCourseLength" :key="index2"> <td> <p>{{ "第" + numberToChinease(item2) + "节" }}</p> </td> <template v-for="(item3, index3) in weeks"> <td :key="index3" :rowspan=" showData(index3, index2 + 1).subject && showData(index3, index2).subject === showData(index3, index2 + 1).subject ? 2 : '' " :style="[ { display: showData(index3, index2 - 1).subject && showData(index3, index2 - 1).subject === showData(index3, index2).subject ? 'none' : '', }, ]" > <div class="dmsjandjs-b" :style="[ { background: showData(index3, index2).index ? getRandomColor() : '#FFFFFF', }, { color: '#fff' }, { borderRadius: '15px' }, { padding: '12px' }, { height: '100%' }, ]" > <p> {{ showData(index3, index2).startTime }} {{ showData(index3, index2).startTime ? "-" : "" }} {{ showData(index3, index2).endTime }} </p> <p>{{ showData(index3, index2).subject }}</p> <p>{{ showData(index3, index2).major }}</p> <p>{{ showData(index3, index2).class }}</p> </div> </td> </template> </tr> </tbody> </table> </div> </div> </template> <script> import moment from "moment"; import { weekCourse, colorList } from "./Timetable"; export default { data() { return { startTime: "2022.10.17", endTime: "2022.10.23", colorList: [], //随机颜色 weekCourse: [], // 课程详细课程、数量 weeks: [], //头部周期 maxCourseLength: 0, //最大课节数, count: 0, //上周、下周、本周选择器flag }; }, created() { this.weekCourse = weekCourse; this.colorList = colorList; this.sortData(); this.init(); this.getWeek(0); }, methods: { //改变选择器次数 changeCount(i) { this.count += i; return this.count; }, // 排序周期和课数 sortData() { //周期 this.weekCourse.sort((a, b) => { return a.week - b.week; }); this.weekCourse.forEach((item) => { for (const key in item) { if (key === "courses") { item[key].sort((a, b) => { return a.index - b.index; }); } } }); }, // 初始化课数(courses)与天数(week) init() { this.weeks = []; //周集合 this.maxCourseLength = 0; this.weeks = this.weekCourse.map((item, index) => { for (const key in item) { if (key === "courses") { let max = 0; // //取出一周中最大的课节数及当天的最大课节数 for (let j of item[key]) { j.index > this.maxCourseLength && (this.maxCourseLength = j.index); //取所有一周里最大课节值 j.index > max && (max = j.index); //取当天最大课节值 } // console.log("max:", max); //如果当天的课节总数小于当天的最大课节值 if (item[key].length < max) { //以最大课节值为终点遍历当天课节 for (let i = 0; i < max; i++) { //如果下标课节不存在或着与循环的下标不匹配 if (!item[key][i] || item[key][i].index != i + 1) { item[key].splice(i, 0, " "); //填充空课节 } } } } } return item.week; }); }, /** * 处理数据 * @param { Number } weekIndex 周几对应的下标 * @param { Number } courseNum 第几节课对应的下标 * @returns { String } 返回对应字符 */ showData(weekIndex, courseNum) { if ( this.weekCourse[weekIndex] && this.weekCourse[weekIndex].courses[courseNum] && this.weekCourse[weekIndex].courses[courseNum].index === courseNum + 1 ) { // this.getRandomColor(); return this.weekCourse[weekIndex].courses[courseNum]; } return false; }, /** * 数字转中文 * @param { Number } n 需转换的数字 * @param { Boolean } identifier 标识符 * @returns { String } identifier 转换后的中文 */ numberToChinease(n, identifier) { const chnArr = [ "零", "一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二", ]; return identifier === "week" && (n === 0 || n === 7) ? "日" : chnArr[n]; }, //随机获取颜色 getRandomColor() { let colorList = this.colorList; let colorRandom = Math.floor(Math.random() * colorList.length + 1) - 1; let color; for (let i = 0; colorList.length > i; i++) { if (i == colorRandom) { color = colorList[i]; } } return color; }, //随机上、本、下周 日期 getWeek(i) { let weekOfDay = parseInt(moment().format("E")); //计算今天是这周第几天 let last_monday = moment() .subtract(weekOfDay + 7 * i - 1, "days") .format("YYYY-MM-DD"); //周一日期 let last_sunday = moment() .subtract(weekOfDay + 7 * (i - 1), "days") .format("YYYY-MM-DD"); //周日日期 this.startTime = last_monday; this.endTime = last_sunday; }, }, }; </script> <style scoped lang="scss"> .timetable { background-color: #f1f7ff; .w100 { width: 100% !important; } .h100 { height: 100% !important; } .time-b { height: 46px; margin-bottom: 24px; display: flex; align-items: center; justify-content: space-between; .time-detail { color: #333333; font-weight: 700; font-size: 20px; font-family: "Microsoft YaHei"; } } .timetable-b { height: 1207px; background-color: #fff; overflow: auto; .timetable-content { height: 100%; table-layout: fixed; border-collapse: collapse; //设置表格的边框是否被合并为一个单一的边框 text-align: center; color: #333333; font-weight: 400; font-size: 18px; thead { height: 100px; th { border: 2px solid rgba(27, 100, 240, 0.1); } } tbody { height: calc(100% - 2px) / 7; td { padding: 12px; border: 2px solid rgba(27, 100, 240, 0.1); .dmsjandjs-b { display: flex; flex-direction: column; justify-content: center; } } } } } } ::v-deep { .time-controller { .el-button-group { .el-button { height: 46px; background: #ffffff; font-size: 18px; font-weight: 600; border: 1px solid rgba(27, 100, 240, 0.1); border-radius: 55px; color: #1b64f0; } :nth-child(2) { margin: 0px 12px; } } } } </style>
复制