1 封装 components
<template>
<view style="padding-bottom: 100rpx;">
<view class="header flex_sb">
<div class="header_list flex" v-for="(item,index) in timeList" :key="item.value">
<div>{{item.text}}</div>
<div>{{item.value}}</div>
</div>
</view>
<div class="left">
<div class="box" v-for="(item,index) in dayTime" :key="index">
<div class="left_list flex">
<div style="color: #000;font-size: 30rpx;">{{index + 1}}</div>
<div>{{item.startTime}}</div>
<div>{{item.endTime}}</div>
</div>
</div>
</div>
<div class="content">
<div class="week" v-for="(item,index) in courseData" :key="index">
<div class="course_list" v-for="(course,courseIndex) in item" :key="courseIndex">
<div class="course" :style="{height:(course.length * 150) + 'rpx',background:course.backgroundColor}" v-if="course.length > 0">
{{course.name}}
</div>
</div>
</div>
</div>
</view>
</template>
<script>
export default {
props:{
data:{
type:Array,
default:() => []
},
palette:{
type:Array,
default:() => []
},
timeList:{
type:Array,
default:() => {
return [{
text:'星期',
value:'日期'
},{
text:'周一',
value:'02-02'
},{
text:'周二',
value:'02-03'
},{
text:'周三',
value:'02-04'
},{
text:'周四',
value:'02-05'
},{
text:'周五',
value:'02-06'
},{
text:'周六',
value:'02-07'
},{
text:'周日',
value:'02-08'
}]
}
},
dayTime:{
type:Array,
default:() => {
return [{
startTime:'08:10',
endTime:'09:55'
},{
startTime:'09:05',
endTime:'09:50'
},{
startTime:'10:10',
endTime:'10:55'
},{
startTime:'11:05',
endTime:'11:50'
},{
startTime:'14:00',
endTime:'14:45'
},{
startTime:'14:55',
endTime:'15:40'
},{
startTime:'16:00',
endTime:'16:45'
},{
startTime:'16:55',
endTime:'17:40'
},{
startTime:'18:10',
endTime:'18:55'
},{
startTime:'17:05',
endTime:'17:50'
},{
startTime:'20:10',
endTime:'20:55'
},{
startTime:'21:05',
endTime:'21:50'
}]
}
}
},
data(){
return {
allPalette: [...this.palette,'#f05261', '#48a8e4', '#ffd061', '#52db9a',
'#70d3e6', '#52db9a', '#3f51b5', '#f3d147', '#4adbc3', '#673ab7',
'#f3db49', '#76bfcd', '#b495e1', '#ff9800', '#8bc34a'],
}
},
computed:{
courseData(){
/** 为数据标记背景颜色的函数 */
let paletteIndex = 0
const getBackgroundColor = () => {
const backgroundColor = this.allPalette[paletteIndex]
paletteIndex++
if(paletteIndex >= this.allPalette.length){
paletteIndex = 0
}
return backgroundColor
}
/** 合并数据 */
const listMerge = []
this.data.forEach((list,i) => {
if(!listMerge[i]) listMerge[i] = []
list.forEach((item,index) => {
if (!index) {
return listMerge[i].push({ name: item, length: 1, backgroundColor: item === '' ? 'none' : getBackgroundColor() })
}
if (item === (listMerge[i][index - 1] || {}).name && item) {
const sameIndex = (listMerge[i][index - 1] || {}).sameIndex
if (sameIndex || sameIndex === 0) {
listMerge[i][sameIndex].length++
return listMerge[i].push({ name: item, length: 0, sameIndex: sameIndex })
}
listMerge[i][index - 1].length++
return listMerge[i].push({ name: item, length: 0, sameIndex: index - 1 })
} else {
return listMerge[i].push({ name: item, length: 1, backgroundColor: item === '' ? 'none' : getBackgroundColor() })
}
})
})
return listMerge
}
}
}
</script>
<style lang="scss">
.header{
position: relative;
padding: 0 20rpx;
font-size: 26rpx;
&_list{
flex-direction: column;
height: 100rpx;
font-weight: 600;
}
}
.left{
width: 100%;
.box{
width: 100%;
&::after{
content: "";
position: absolute;
left: 0;
width: 100%;
height: 1rpx;
background: #999;
}
}
&_list{
flex-direction: column;
height: 150rpx;
color: #6a855c;
font-size: 12rpx;
width: 11%;
background: #fae3f9;
}
}
.content{
position: relative;
position: absolute;
top: 100rpx;
left: 88rpx;
width: calc(100% - 88rpx);
height: 100%;
display: flex;
.week{
flex: 1;
width: 0;
flex-grow: 1;
display: flex;
flex-direction: column;
}
.course_list{
word-break: break-all;
color: white;
}
.course{
border-radius: 10rpx;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
font-size: 16rpx;
padding: 0 4rpx;
width: 90%;
}
}
</style>
2 页面中使用
<template>
<timetable :data="timetables"></timetable>
</template>
<script>
import Timetable from '@/components/timetable.vue'
export default {
components:{Timetable},
data() {
return {
timetables: [
['大学英语', '大学英语', '大学英语', '', '', '', '毛概', '毛概', '', '', '', '选修'],
['', '', '信号与系统', '信号与系统', '模拟电子技术基础', '模拟电子技术基础', '', '', '', '', '', ''],
['大学体育', '大学体育', '形势与政策', '形势与政策', '', '', '', '', '', '', '', ''],
['', '', '', '', '电装实习', '电装实习', '', '', '', '大学体育', '大学体育', ''],
['', '', '数据结构与算法分析', '数据结构与算法分析', '', '', '', '', '信号与系统', '信号与系统', '', ''],
['', '', '数据结构与算法分析', '数据结构与算法分析', '', '', '', '', '信号与系统', '信号与系统', '', ''],
['', '', '数据结构与算法分析', '数据结构与算法分析', '', '', '', '', '信号与系统', '信号与系统', '', '']
]
}
}
}
</script>
3 效果图