思路
将课程表想象成一个坐标轴,横坐标为星期,纵坐标为节数,利用HTML5新增拖动事件,通过e.target判断拖拽结束的“坐标”,确认最后拖动的位置
<div class="schedule-table">
<table>
<thead>
<tr>
<th colspan="2"></th>
<th v-for="(val,weekindex) in weeks" :key="weekindex">{{val}}</th>
</tr>
</thead>
<tbody>
<tr v-for="index of 11" :key="index">
<td class="week-td" rowspan="4" v-if="index==1">上午</td>
<td class="week-td" rowspan="4" v-if="index==5">下午</td>
<td class="week-td" rowspan="3" v-if="index==9">晚上</td>
<td class="week-td">{{index}}</td>
<td draggable="true" @dragend="drop($event)" @dragover="allowDrop($event)" v-for="(val,weekindex) in weeks" :key="weekindex" :dataindex="index" :week="val">{{fieldCharacter(val, index)}}</td>
</tr>
</tbody>
</table>
</div>
data里面的数据结构
使用组件将传过来的值直接赋值给tableData,data两个数组(数据一样),这里由于方便看数据结构,直接定义到data里面了
data() {
return {
tableData:[{
courseweek:'星期一',
courseperiod:1,
courseidentity:'AAA'
},{
courseweek:'星期二',
courseperiod:1,
courseidentity:'BBB'
},{
courseweek:'星期三',
courseperiod:1,
courseidentity:'CCC'
},{
courseweek:'星期四',
courseperiod:1,
courseidentity:'DDD'
},{
courseweek:'星期五',
courseperiod:1,
courseidentity:'EEE'
},{
courseweek:'星期六',
courseperiod:1,
courseidentity:'FFF'
},{
courseweek:'星期日',
courseperiod:1,
courseidentity:'GGG'
},{
courseweek:'星期一',
courseperiod:2,
courseidentity:'DDD'
},{
courseweek:'星期二',
courseperiod:2,
courseidentity:'AAA'
},{
courseweek:'星期三',
courseperiod:2,
courseidentity:'BBB'
},{
courseweek:'星期四',
courseperiod:11,
courseidentity:'BBB'
}],
weeks:['星期一','星期二','星期三','星期四','星期五','星期六','星期日'],
endIndex:0,
week:'',
data:[{
courseweek:'星期一',
courseperiod:1,
courseidentity:'AAA'
},{
courseweek:'星期二',
courseperiod:1,
courseidentity:'BBB'
},{
courseweek:'星期三',
courseperiod:1,
courseidentity:'CCC'
},{
courseweek:'星期四',
courseperiod:1,
courseidentity:'DDD'
},{
courseweek:'星期五',
courseperiod:1,
courseidentity:'EEE'
},{
courseweek:'星期六',
courseperiod:1,
courseidentity:'FFF'
},{
courseweek:'星期日',
courseperiod:1,
courseidentity:'GGG'
},{
courseweek:'星期一',
courseperiod:2,
courseidentity:'DDD'
},{
courseweek:'星期二',
courseperiod:2,
courseidentity:'AAA'
},{
courseweek:'星期三',
courseperiod:2,
courseidentity:'BBB'
},{
courseweek:'星期四',
courseperiod:11,
courseidentity:'BBB'
}],
nav:{
zd:0,
sw:5,
xw:2,
ws:3
}
}
},
方法:
fieldCharacter(weekIndex, index){
let info;
for(let i =0;i<this.tableData.length;i++){
// weekIndex就是横坐标代表星期,index是纵坐标代表节数
if(this.tableData[i].courseweek === weekIndex && this.tableData[i].courseperiod === index){
// 当tableData里面数据的星期(courseweek)与weekIndex对应,节数(courseperiod)与index对应,渲染td数据,返回的info就是td里面渲染的数据
info=this.tableData[i].courseidentity
break
}
}
return info||'-'
},
allowDrop(event) {
this.endIndex = event.target.getAttribute("dataindex")-0;
this.week = event.target.getAttribute("week");
},
drop(event) {
let endIndex = event.target.getAttribute("dataindex")-0;
let week = event.target.getAttribute("week");
for(let i =0;i<this.tableData.length;i++){
if(this.tableData[i].courseweek === this.week && this.tableData[i].courseperiod === this.endIndex){
this.tableData[i].courseweek=week
this.tableData[i].courseperiod=endIndex;
break
}
}
console.log(this.data)
console.log(this.data[0].courseweek)
for(let i =0;i<this.data.length;i++){
if(this.data[i].courseweek === week && this.data[i].courseperiod === endIndex){
this.tableData[i].courseweek=this.week
this.tableData[i].courseperiod=this.endIndex
break
}
}
this.data=this.tableData
}
}
针对fieldCharacter()方法的解读
返回的不一定只是一个数据,根据使用的环境可以将这个函数进行处理,比如有多行数据并且还有布局可以使用 info = <p>${this.tableData[i].courseName}</p> <p>${this.tableData[i].teacherName}</p><p>${this.tableData[i].schoolSite}</p>
;然后通过v-html="fieldCharacter(val, index)"进行处理。这个函数根据返回值可以判断各种条件,比如v-html,class的解析判断 :class=“fieldCharacter(val, index)”,具体使用看需求,返回值在fieldCharacter方法里面进行逻辑处理
css样式
.schedule-table{
table {
border: 1px solid #ebebeb;
margin: 20px auto;
text-align: center;
border-collapse: collapse;
}
.week-td{
background-color: #f7f7f7;
}
table th {
border: 1px solid #ebebeb;
background-color: #f7f7f7;
padding: 10px;
width: 100px;
height: 40px;
font-size: 14px;
}
table td {
border: 1px solid #ebebeb;
padding: 4px 10px;
height:40px;
color: #000000;
font-size: 14px;
}
}
如果组件成功引入效果图: