之前用的课程表基本都是基于calendar开发的,calendar功能比较丰富,能实现很多功能,但是基于学校项目来说并不完美,首先就是最左侧的时间轴,学校课程表一般都是节次,而calendar都是时间。因为学校夏季和冬季上课时间都不同,所以并不实用。而有的calendar组件封装的比较厉害,想改造是很麻烦的,正是基于此我自己写了一个基础版本的课程表,分享给有需要的朋友。
上面是课程表的截图,样式是采用正方教务的课程表样式,大部分学校用的都是正方的教务系统,这种样式老师和学生都能接受。如果不想用这种样式,也可以自己修改,代码比较简单。
课程表最左侧是时间段:上午、下午和晚上。第二列是节次,节次上午固定为4节课,下午的节次是可扩展的,只需要传入一个值即可,因为在做项目的过程中遇到过学校下午是5节课的,4节课的都有,所以做了一个可变动的。晚上的节次是根据总节次和上午,下午的节次算出来的,所有在调用组件的时候,需要传入总节次和下午的节次。
课程表内容展示了一周7天,可以根据实际情况进行调整 。内容比较简单,标题和内容,标题是课程名称,内容可以自由拼接,在渲染的时候用的v-html,因此在拼接内容时,可以自由拼接一些html元素,让内容更好看。并且课程表数据中还有一个class属性,可以传入不同的class自定义一些样式。(这个版本只是有,但并未使用)
整个课程表的内容大概就是这些,比较简单,但是挺实用,而且可以自己根据项目需要进行修改,比如添加点击事件,修改样式等等。
直接上代码:
<template>
<div>
<div class="panel">
<el-table :data="timetable" :span-method="objectSpanMethod" border
:header-cell-style="{background:'#d9e5fd', color:'black', fontWeight: 1000}"
:cell-style="tableCellStyle"
>
<el-table-column prop="sjd" label="时间段" width="80" align="center">
</el-table-column>
<el-table-column prop="jc" label="节次" width="80" align="center">
</el-table-column>
<el-table-column prop="mon" label="星期一" align="center">
<template slot-scope="scope">
<h4>{{ scope.row.mon.title }}</h4>
<div v-html="scope.row.mon.content"></div>
</template>
</el-table-column>
<el-table-column prop="tue" label="星期二" align="center">
<template slot-scope="scope">
<h4>{{ scope.row.tue.title }}</h4>
<div v-html="scope.row.tue.content"></div>
</template>
</el-table-column>
<el-table-column prop="wed" label="星期三" align="center">
<template slot-scope="scope">
<h4>{{ scope.row.wed.title }}</h4>
<div v-html="scope.row.wed.content"></div>
</template>
</el-table-column>
<el-table-column prop="thu" label="星期四" align="center">
<template slot-scope="scope">
<h4>{{ scope.row.thu.title }}</h4>
<div v-html="scope.row.thu.content"></div>
</template>
</el-table-column>
<el-table-column prop="fri" label="星期五" align="center">
<template slot-scope="scope">
<h4>{{ scope.row.fri.title }}</h4>
<div v-html="scope.row.fri.content"></div>
</template>
</el-table-column>
<el-table-column prop="sat" label="星期六" align="center">
<template slot-scope="scope">
<h4>{{ scope.row.sat.title }}</h4>
<div v-html="scope.row.sat.content"></div>
</template>
</el-table-column>
<el-table-column prop="sun" label="星期日" align="center">
<template slot-scope="scope">
<h4>{{ scope.row.sun.title }}</h4>
<div v-html="scope.row.sun.content"></div>
</template>
</el-table-column>
</el-table>
</div>
</div>
</template>
<script>
export default {
props: {
// 下午节次数
afternoonLength: {
type: [String, Number],
default: 4
},
// 总节次
length: {
type: [String, Number],
default: 12
},
// 课表数据
events: {
type: Array,
default: null
}
},
data () {
return {
// 课程表数据
timetable: [],
events1: [
{
xq: 1,
title: '形势与政治',
class: 'sport',
content: '1-4节' + '/' + '社会学1班' + '/' + '5教-402室',
start: 1,
end: 4
},
{
xq: 1,
title: '形势与政治',
class: 'leisure',
content: '9-12节' + '<br>' + '社会学2班' + '<br>' + '5教-401室',
start: 9,
end: 12
},
{
xq: 3,
title: '形势与政治',
class: 'sport',
content: '5-6节' + '/' + '社会学2班' + '/' + '1教-401室',
start: 5,
end: 6
},
{
xq: 4,
title: '形势与政治',
class: 'sport',
content: '1-2节' + '/' + '社会学1班' + '/' + '5教-402室',
start: 1,
end: 2
},
{
xq: 4,
title: '形势与政治',
class: 'sport',
content: '7-8节' + '/' + '社会学1班' + '/' + '5教-402室',
start: 7,
end: 8
},
{
xq: 5,
title: '形势与政治',
class: 'sport',
content: '社会学1班' + '/' + '5教-402室',
start: 3,
end: 4
},
{
xq: 5,
title: '形势与政治',
class: 'sport',
content: '5-6节' + '/' + '社会学1班' + '/' + '5教-402室',
start: 5,
end: 6
}
],
hoverOrderArr: [],
weeks: ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']
}
},
mounted () {
this.mergeData()
},
watch: {
events: {
handler (newVal, oldVal) {
this.mergeData()
},
deep: true
}
},
created () {
this.makeTimetable()
},
methods: {
// 单元格添加背景色
tableCellStyle (row) {
if (row.row[row.column.property].title !== undefined) {
return 'background-color:rgb(24 144 255 / 80%);color: #fff; border-radius:10px'
}
},
// 构造课程表完整数据
makeTimetable () {
this.timetable = []
for (let i = 0; i < this.length; i++) {
let one = {
sjd: '',
jc: i + 1,
mon: {},
tue: {},
wed: {},
thu: {},
fri: {},
sat: {},
sun: {}
}
if (i < 4) {
one.sjd = '上午'
} else if (i > 3 && i < (this.afternoonLength + 4)) {
one.sjd = '下午'
} else {
one.sjd = '晚上'
}
this.timetable.push(one)
}
},
mergeData () {
// 合并数据
if (this.events.length > 0) {
for (let i = 0; i < this.events.length; i++) {
// 获取星期几
let week = this.weeks[this.events[i].xq - 1]
this.timetable[this.events[i].start - 1][week] = this.events[i]
}
}
},
objectSpanMethod ({ row, column, rowIndex, columnIndex }) {
if (columnIndex === 0) {
if (rowIndex < 4) {
if (rowIndex === 0) {
return {
rowspan: 4,
colspan: 1
}
} else {
return {
rowspan: 0,
colspan: 0
}
}
} else if (rowIndex > 3 && rowIndex < (4 + this.afternoonLength)) {
if (rowIndex === 4) {
return {
rowspan: this.afternoonLength,
colspan: 1
}
} else {
return {
rowspan: 0,
colspan: 0
}
}
} else {
if (rowIndex === (4 + this.afternoonLength)) {
return {
rowspan: this.length - 4 - this.afternoonLength,
colspan: 1
}
} else {
return {
rowspan: 0,
colspan: 0
}
}
}
}
if (columnIndex === 2) {
if (row.mon.title !== undefined) {
return {
rowspan: row.mon.end - row.mon.start + 1,
colspan: 1
}
} else {
return {
rowspan: 1,
colspan: 1
}
}
}
if (columnIndex === 3) {
if (row.tue.title !== undefined) {
return {
rowspan: row.tue.end - row.tue.start + 1,
colspan: 1
}
} else {
return {
rowspan: 1,
colspan: 1
}
}
}
if (columnIndex === 4) {
if (row.wed.title !== undefined) {
return {
rowspan: row.wed.end - row.wed.start + 1,
colspan: 1
}
} else {
return {
rowspan: 1,
colspan: 1
}
}
}
if (columnIndex === 5) {
if (row.thu.title !== undefined) {
return {
rowspan: row.thu.end - row.thu.start + 1,
colspan: 1
}
} else {
return {
rowspan: 1,
colspan: 1
}
}
}
if (columnIndex === 6) {
if (row.fri.title !== undefined) {
return {
rowspan: row.fri.end - row.fri.start + 1,
colspan: 1
}
} else {
return {
rowspan: 1,
colspan: 1
}
}
}
if (columnIndex === 7) {
if (row.sat.title !== undefined) {
return {
rowspan: row.sat.end - row.sat.start + 1,
colspan: 1
}
} else {
return {
rowspan: 1,
colspan: 1
}
}
}
if (columnIndex === 8) {
if (row.sun.title !== undefined) {
return {
rowspan: row.sun.end - row.sun.start + 1,
colspan: 1
}
} else {
return {
rowspan: 1,
colspan: 1
}
}
}
}
}
}
</script>复制
调用的时候的代码: