菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
225
0

日程表

原创
05/13 14:22
阅读数 30256

vue实现一个简单的日程表:

写在home.vue文件中了

<template>
    <div class="homeBox">
        <table>
            <!-- 时间轴 -->
            <tr>
                <td ><div :style="{width:2*tableWidth+'px',height:tableHeight+'px'}"></div></td>
                <td v-for="(item,index) in arrLength" :key="index">
                    <div class="timeWrap" :style="{width:tableWidth+'px',height:tableHeight+'px'}">
                        <span>{{minTOhm(index,step,startTime)}}</span>
                    </div>
                </td>
            </tr>
            <!-- 表格 -->
            <tr v-for="(tableItem,index) in sessionDataArr" :key="'table'+index">
                <td ><div class="roomName" :style="{width:2*tableWidth+'px',height:tableHeight+'px',lineHeight:tableHeight+'px'}">{{tableItem.roomName}}</div></td>
                <td v-for="(item,index) in tableItem.sessionArr"
                    class="itemcell"
                    :key="index+'tableItem'" 
                    :colspan="item.colspan?item.colspan:''">
                    <div class="itemTd" 
                        :style="{width:item.colspan?(item.colspan*tableWidth)+'px':tableWidth+'px',height:tableHeight+'px'}"
                        :title="item.text">
                        <a class="linkEle" href="javascript:">
                            <span class="session_text">{{item.text}}</span>
                        </a>
                    </div>
                </td>
            </tr>
        </table>
    </div>
</template>

<script>
// @ is an alias to /src
import tools from "@/util/tools.js";
import global from "@/util/global.js";
import api from "@/util/api.js";
export default {
    name: "home",
    components: {
    },
    data(){
        return{
            tableWidth:50,
            tableHeight:50,
            startTime:"08:00",//日程开始时间
            endTime:"22:15",//日程结束时间
            step:10,//时间间隔
            sessionData:[//模拟的session数据
                {
                    roomName:"多功能厅A",
                    sessionArr:[
                        {startTime:"08:00",endTime:"08:30",text:"心血管研究心血管研究",colspan:""},
                        {startTime:"09:00",endTime:"09:10",text:"心血管研究",colspan:""},
                        {startTime:"09:20",endTime:"09:30",text:"是打发",colspan:""},
                        {startTime:"09:40",endTime:"10:00",text:"分发大时分发时分发送到",colspan:""},
                    ]
                },
                {
                    roomName:"多功能厅B",
                    sessionArr:[
                        {startTime:"08:00",endTime:"08:50",text:"sessionB心血管研究",colspan:""},
                        {startTime:"09:00",endTime:"09:10",text:"大脑研究",colspan:""},
                        {startTime:"15:20",endTime:"15:50",text:"哈哈哈",colspan:""},
                        {startTime:"21:00",endTime:"21:20",text:"分发大时",colspan:""},
                    ]
                },
                {
                    roomName:"多功能厅C",
                    sessionArr:[
                        {startTime:"08:00",endTime:"08:50",text:"sessionB心血管研究",colspan:""},
                        {startTime:"09:00",endTime:"09:10",text:"大脑研究",colspan:""},
                        {startTime:"15:20",endTime:"15:50",text:"哈哈哈",colspan:""},
                        {startTime:"21:00",endTime:"21:20",text:"分发大时",colspan:""},
                    ]
                },
            ],

            arrLength:0,//总共与多上格子(不用后台传,是计算出来的))
            sessionDataArr:[],//根据后台数据 生成的最终表格数据(不用后台传)
        }
    },
    created(){
        this.generaterAllTable(this.sessionData);//生成整个表格数据  
    },
    mounted(){
       
    },
    methods:{
        hmTOmin(hm){//hh:mm=>分钟或则秒
            var arr=hm.split(":"),H,M,sum={M:'',S:''};
            if(/^0[0-9]$/.test(arr[0])){
                H=Number(arr[0].replace("0",''));
            }else{
                H=Number(arr[0]);
            }
            if(/^0[0-9]$/.test(arr[1])){
                M=Number(arr[1].replace("0",''));
            }else{
                M=Number(arr[1]);
            }
            sum.M=Number(H*60+M);
            sum.S=Number((H*60+M)*60);
            return sum;
        },
        minTOhm(index,step,startTime){//计算时间轴
            var str="",h,m,self=this;
            if(index==0){
                str=startTime;
            }else{
                var sumMIn=self.hmTOmin(startTime).M+(step*index);
                h=parseInt(sumMIn/60);
                m=sumMIn%60;
                if(h<10){
                    h='0'+h;
                }
                if(m<10){
                    m='0'+m;
                }
                str=h+":"+m;
            }
            return str;
        },
        generaterCol(sessionArr){//生成某一列的session数组
            var self=this,colArr=[];
            self.generaterArrLength();//计算时间轴的长度 下面能用到
            var sessionTd=0;//session所占的总格数
            sessionArr.forEach((item,index,arr)=>{
                item.colspan=Math.ceil((self.hmTOmin(item.endTime).M-self.hmTOmin(item.startTime).M)/self.step);
                sessionTd+=item.colspan;
            })
            
            var tableColArrLength=self.arrLength-sessionTd+sessionArr.length;//日程某一列有多少个单元格,也就是某一列数组的长度
            
            for(let i=0,len=tableColArrLength;i<len;i++){//可以考虑抽离出去
                var obj={startTime:"",endTime:"",text:"",colspan:""};
                colArr[i]=obj;
            }

            function addData(){//向某一列数组中添加数据
                var count=0;//计算每个session前面有
                sessionArr.forEach((item,index,arr)=>{
                    var itemIndex=Math.floor((self.hmTOmin(item.startTime).M-self.hmTOmin(self.startTime).M)/self.step);
                    colArr[itemIndex-count].startTime=item.startTime;
                    colArr[itemIndex-count].endTime=item.endTime;
                    colArr[itemIndex-count].text=item.text;
                    colArr[itemIndex-count].colspan=item.colspan;
                    count+=(item.colspan-1);
                })
            }
            addData();
            return colArr;//将生成的某一列数据返回出去
        },
        generaterArrLength(){//计算出事件轴的长度
            var self=this;
            var sumMIN=self.hmTOmin(self.endTime).M-self.hmTOmin(self.startTime).M;
            self.arrLength=Math.ceil(sumMIN/self.step);//总共有多少格子
        },
        generaterAllTable(sessionData){//生成整个session表
            var self=this,arr=[];
            sessionData.forEach((item,index,arr)=>{
                var obj={
                    roomName:"",
                    sessionArr:[],
                };
                obj.roomName=item.roomName;
                obj.sessionArr=self.generaterCol(item.sessionArr);
                self.sessionDataArr.push(obj);
            });
            console.log(self.sessionDataArr);
        }
    }
};
</script>

<style scoped>
    .homeBox{
    }
    @media screen and (max-width:768px){
        .min768{
            display:block;
        }
        .max768{
            display: none;
        }
    }
    @media screen and (min-width:768px){
        .min768{
            display:none;
        }
        .max768{
            display: block;
        }
    }
    .timeWrap{
        position: relative;
    }
    .timeWrap span{
        position: absolute;
        bottom:0;
        left:0;
        transform-origin: left bottom;
        transform:rotateZ(-45deg)
    }
    .itemTd{
        border:2px solid #ffffff;
        border-radius:5px;
        background:brown;
        box-sizing: border-box;
        text-align: center;
        position: relative;
    }
    .session_text{
        position: absolute;
        top:50%;
        width:100%;
        transform: translateY(-50%);
        display: -webkit-box;
        overflow: hidden;
        white-space: normal;
        text-overflow: ellipsis;
        word-wrap: break-word;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
    }
    .itemcell{
        vertical-align: middle;
    }
    .roomName{
        border:2px solid #ffffff;
        border-radius:5px;
        background:yellow;
        text-align: center;
        box-sizing: border-box;
    }
    .linkEle{
        text-decoration: none;
        color:black;
    }
</style>

。。。

 另一种实现:

<template>
    <div class="scheduleBox">
        <div class="contentBox padding0">
            <div class="topImgBox">
                <img :src="bannerImgUrl" alt="banner图">
            </div>
            <!-- 检索框 -->
            <div class="row paddingTB bottomBorder margin0">
                <div class="col col-xs-1 title lineHeight text-right">模糊搜索:</div>
                <div class="col col-xs-6">
                    <div>
                        <el-input v-show="searchPattern=='姓名'" placeholder="请输入专家姓名/讲题进行搜索" v-model="realName" class="input-with-select">
                            <el-select v-model="searchPattern" slot="prepend" style="width:130px;" placeholder="请选择">
                                <el-option label="姓名" value="姓名"></el-option>
                                <el-option label="讲题名称" value="讲题名称"></el-option>
                            </el-select>
                            <el-button @click="clickSearch()" slot="append" icon="el-icon-search"></el-button>
                        </el-input>
                        <el-input v-show="searchPattern=='讲题名称'" placeholder="请输入专家姓名/讲题进行搜索" v-model="jiangti" class="input-with-select">
                            <el-select v-model="searchPattern" slot="prepend" style="width:130px;" placeholder="请选择">
                                <el-option label="姓名" value="姓名"></el-option>
                                <el-option label="讲题名称" value="讲题名称"></el-option>
                            </el-select>
                            <el-button @click="clickSearch()" slot="append" icon="el-icon-search"></el-button>
                        </el-input>
                    </div>
                </div>
                <div class="col col-xs-5">

                </div>
            </div>
            <!-- 选择日期     -->
            <div class="row paddingTB bottomBorder margin0">
                <div class="col col-xs-1 title lineHeight28 text-right">选择日期:</div>
                <div class="col col-xs-11">
                    <ul class="timeBox">
                        <li class="time_item" @click="clickDate('')" :class="{'dateActive':date==''}">不限</li>
                        <li class="time_item" @click="clickDate(item.value)" :class="{'dateActive':date==item.value}" v-for="(item,index) in dateList" :key="'date'+index">
                            <a href="javascript:">{{item.value}}</a>
                        </li>
                    </ul>
                </div>
            </div>
            <!-- 日程一览表 -->
            <div class="schedule_wraper" v-if="schedule_show">
                <table>
                    <tr class="topBox">
                        <td>
                            <div class="table_header_box" style="border-radius:0;" :style="{height:tableHeight+'px'}"></div>
                        </td>
                        <td>
                            <div class="timeRow" :style="{width:(sumMin*control)+'px',height:tableHeight+'px'}">
                                <div class="timeCol" 
                                v-for="(item,index) in arrLength" :key="index"
                                :style="{left:(index*step*control)+'px'}">
                                    <span class="timeText">{{minTOhm(index,step,startTime)}}</span>
                                </div>
                            </div>
                        </td>
                    </tr>
                    <tr class="scheduleRows" v-for="(parentItem,index) in sessionDataArr" :key="'parent'+index">
                        <td>
                            <div :style="{height:tableHeight+'px'}"class="table_header_box" :title="parentItem.cn_name">
                                <span class="room_name">
                                    {{parentItem.cn_name}}
                                </span>
                            </div>
                        </td>
                        <td >
                            <div class="eleRow" :style="{width:(sumMin*control)+'px',height:tableHeight+'px'}">
                                <div class="eleCol" 
                                :title="childItem.cn_name"
                                v-for="(childItem,index) in parentItem.sessionArr" :key="'child'+index"
                                :style="{left:(childItem.startMin*control)+'px',width:(childItem.sumMin*control)+'px',height:(tableHeight-2)+'px'}"
                                >
                                    <span class="eleCol_text">
                                        {{childItem.cn_name}}
                                    </span>
                                </div>
                            </div>
                        </td>
                    </tr>
                </table>
            </div>
        </div>
    </div>
</template>

<script>
import api from "@/util/api.js";
import global from "@/util/global.js";
import tools from "@/util/tools.js";
export default {
    watch:{
        searchPattern:{
            handler(newVal,oldVal){
                if(newVal=='姓名'){
                    this.jiangti="";
                }else{
                    this.realName="";
                }
            },
            immediate:true,
        }
    },
    data(){
        return {
            searchPattern:"姓名",//用户是按'姓名'精确检索的还是按'讲题'精确搜索的
            jiangti:"",//讲题名
            realName:"",//姓名(模糊搜索时)
            date:"",//会场日期
            dateList:[],//日期列表
            mid:this.$route.params.mid,//会议id
            schedule_show:false,//控制一览表的显示隐藏
            //以下是日程一览相关
            control:1,//精度值 1分钟代表多少像素、有总宽度和总分钟计算得出
            fixedWidth:0,//后端后去的表的总宽度(px)
            tableHeight:50,
            startTime:"08:00",//日程开始时间
            endTime:"18:00",//日程结束时间
            step:30,//时间间隔
            arrLength:0,//总共与多上格子(不用后台传,是计算出来的))
            sumMin:0,//session总共有多少分钟
            sessionDataArr:[],//根据后台数据 生成的最终表格数据(不用后台传)


            sessionData:[//模拟的session数据
                {
                    cn_name:"多功能厅A",
                    sessionArr:[
                        {startTime:"08:00",endTime:"08:30",text:"心血管研究心血管研究",colspan:""},
                        {startTime:"09:00",endTime:"09:10",text:"心血管研究",colspan:""},
                        {startTime:"09:20",endTime:"09:30",text:"是打发",colspan:""},
                        {startTime:"09:40",endTime:"10:00",text:"分发大时分发时分发送到",colspan:""},
                    ]
                },
                {
                    cn_name:"多功能厅B",
                    sessionArr:[
                        {startTime:"08:00",endTime:"08:50",text:"sessionB心血管研究",colspan:""},
                        {startTime:"09:00",endTime:"09:10",text:"大脑研究",colspan:""},
                        {startTime:"15:20",endTime:"15:50",text:"哈哈哈",colspan:""},
                        {startTime:"21:00",endTime:"21:20",text:"分发大时",colspan:""},
                    ]
                },
                {
                    cn_name:"多功能厅C",
                    sessionArr:[
                        {startTime:"08:00",endTime:"08:50",text:"sessionB心血管研究",colspan:""},
                        {startTime:"09:00",endTime:"09:10",text:"大脑研究",colspan:""},
                        {startTime:"15:20",endTime:"15:50",text:"哈哈哈",colspan:""},
                        {startTime:"21:00",endTime:"21:20",text:"分发大时",colspan:""},
                    ]
                },
            ],
        }
    },
    created(){
        var self=this;
        self.scheduleInit();
    },
    mounted(){

    },
    methods:{
        scheduleInit(){//初始化
            var self=this;
            self.getMeetingInfo();//获取会议信息
            self.getMeetingDateList().then(()=>{//获取会议日期列表,
                // console.log(self.dateList);
                if(self.dateList.length>0){//默认显示 第一个时间的一览表
                    self.date=self.dateList[0].value;
                }
                self.oncegeneraterSchedule(self.date);//根据日期 生成一览表
            });

            
        },
        oncegeneraterSchedule(date){//根据日期 一次性生成一览表
            var self=this;
            self.getScheduleData(date).then((data)=>{//获取日程一览表数据
                //生成日程表
                self.generaterArrLength();//计算出格子总数
                self.sessionDataArr=self.generaterScheduleData(data);//生成最终数据
                self.control=self.fixedWidth/self.sumMin;//后端给一个指定的宽度,计算出1分钟=多少像素
                self.schedule_show=true;//显示一览表
            });
        },
        getMeetingInfo(){//获取会议信息
            var self=this;
            var obj={
                mid:self.mid
            }
            api.get(global.xuehui+"/pcRcInterface/getMeet",obj,res=>{
                console.log(res)
                if(res.data.success){
                    self.bannerImgUrl=res.data.data.cn_banner_img;
                }else{
                    tools.msgErr(res.data.message);
                }
            },err=>{
                console.log(err);
            })
        },
        getMeetingDateList(){//获取会议日期列表
            var self=this;
            return new Promise((resolve,reject)=>{
                api.get(global.xuehui+"/pcRcInterface/listDate",{mid:self.mid},res=>{
                    if(res.data.success){
                        self.dateList=res.data.data;
                        resolve();
                    }else{
                        self.dateList=[];
                        tools.msgErr(res.data.message||'error');
                    }
                },err=>{
                    console.log(err);
                })
            })  
        },
        clickDate(date){//点击日期项
            var self=this;
            self.schedule_show=false;//隐藏一览表
            self.date=date;
            if(!date){
                if(self.dateList.length>0){//默认显示 第一个时间的一览表
                    self.date=self.dateList[0].value;
                }
            }
            self.oncegeneraterSchedule(self.date);
        },
        //以下是日程一览相关
        getScheduleData(date){//获取日程一览表数据
            var self=this;
            console.log(date);
            return new Promise((resolve,reject)=>{
                var obj={
                    mid:self.mid,//会议唯一标识
                    date:date,//所需一栏表的日期
                    lang:1,//中英文 1:中文  2:英文
                }
                api.get(global.xuehui+"/pcRcInterface/getScheduleAll",obj,res=>{
                    self.startTime=res.data.data.startTime;
                    self.endTime=res.data.data.endTime;
                    self.fixedWidth=res.data.data.fixedWidth?res.data.data.fixedWidth:1200;//拿到最大表的宽度
                    self.step=res.data.data.step;
                    self.tableHeight=res.data.data.tableHeight
                    resolve(res.data.data.RoomData);
                },err=>{
                    console.log(err);
                })
            })
                
        },
        hmTOmin(hm){//hh:mm=>分钟或则秒
            var arr=hm.split(":"),H,M,sum={M:'',S:''};
            if(/^0[0-9]$/.test(arr[0])){
                H=Number(arr[0].replace("0",''));
            }else{
                H=Number(arr[0]);
            }
            if(/^0[0-9]$/.test(arr[1])){
                M=Number(arr[1].replace("0",''));
            }else{
                M=Number(arr[1]);
            }
            sum.M=Number(H*60+M);
            sum.S=Number((H*60+M)*60);
            return sum;
        },
        minTOhm(index,step,startTime){//计算时间轴
            var str="",h,m,self=this;
            if(index==0){
                str=startTime.slice(0,5);
            }else{
                var sumMIn=self.hmTOmin(startTime).M+(step*index);
                h=parseInt(sumMIn/60);
                m=sumMIn%60;
                if(h<10){
                    h='0'+h;
                }
                if(m<10){
                    m='0'+m;
                }
                str=h+":"+m;
            }
            return str;
        },
        generaterArrLength(){//计算出事件轴的长度
            var self=this;
            self.sumMin=self.hmTOmin(self.endTime).M-self.hmTOmin(self.startTime).M;
            self.arrLength=Math.ceil(self.sumMin/self.step);//总共有多少格子
        },
        generaterColArr(sessionArr){//生成某一列的session数组
            var self=this;
            var array=[];
            sessionArr.forEach((item,index,arr)=>{
                item.startMin=self.hmTOmin(item.startTime).M-self.hmTOmin(self.startTime).M;
                item.sumMin=self.hmTOmin(item.endTime).M-self.hmTOmin(item.startTime).M;
            });
            array=sessionArr;
            return array;
        },
        generaterScheduleData(sessionData){//生成整个session表数据
            var self=this;
            var array=[];
            sessionData.forEach((item,index,arr)=>{
                var obj={};
                obj.cn_name=item.cn_name;
                obj.sessionArr=self.generaterColArr(item.sessionArr);
                array.push(obj);
            });
            return array;
        },
        
    }
}
</script>

<style scoped>
    .scheduleBox{

    }
    .contentBox{
        width:100%;
        margin:0 auto;
        box-shadow:0px 0px 0px 0px #e0e0e0,   /*上边阴影*/
                -5px 0px 10px 0px #e0e0e0,   /*左边阴影*/
                5px 0px 10px 0px #e0e0e0,    /*右边阴影*/
                0px 0px 0px 0px #e0e0e0;    /*下边阴影*/
        background:#ffffff;
    }
    /* 检索块 */
    .padding0{
        padding:0;
    }
    .paddingTB{
        padding:10px 0;
    }
    .lineHeight{
        line-height:40px;
    }
    .lineHeight28{
        line-height:28px;
    }
    .bottomBorder{
        border-bottom: 1px solid #dddddd;
    }
    .margin0{
        margin:0;
    }
    .title{
        color:#777;
        font-weight: bold;
        font-size:14px;
    }
    
    /* 顶部图 */
    .topImgBox img{
        width:100%;
        height:auto;
    }
    /* 选择日期 */
    .timeBox{
        overflow: hidden;
    }
    .timeBox .dateActive{
        background:#ff7b00;
        color:#ffffff;
        padding: 0 10px;
        border-radius:5px;
        cursor: pointer;
    }
    .timeBox .dateActive a{
        color:#ffffff;
    }
    .time_item{
        float: left;
        line-height:28px;
        color:#333333;
        margin-right:20px;
        padding: 0 10px;
        border-radius:5px;
        cursor: pointer;
    }
    .time_item a{
          text-decoration: none;
        color:#333333;
    }
    .time_item:hover{
        color:#ffffff;
        background:#ff7b00;
    }
    .time_item:hover a{
        color:#ffffff;
    }
    /* 日程一览表 */
    .schedule_wraper{
        width:100%;
        overflow-x: auto;
        text-align:center;
        padding:20px 20px 50px;
    }
    .schedule_wraper>table{
        margin:0 auto;
    }
    .topBox{
        background:#0d8cdd;
    }
    .eleRow{
        background:#f1f5f9;
        margin:0 auto;
        position: relative;
        border-bottom:2px solid #ffffff;
        border-radius:6px;
    }
    .eleCol{
        position: absolute;
        /* background:red; */
        border-left:1px solid #ffffff;
        border-right:1px solid #ffffff;
        border-radius:6px;
        top:0;
        background:rgba(1,54,126,.8);
        padding:2px;
        box-sizing: border-box;
        color:#ffffff;
        cursor: pointer;
    }
    .eleCol:hover{
        background:rgba(1,54,126,1);
    }
    .eleCol .eleCol_text{
        position: absolute;
        width:100%;
        top:50%;
        left:0;
        transform: translateY(-50%);
        display: -webkit-box;
        overflow: hidden;
        white-space: normal;
        text-overflow: ellipsis;
        word-wrap: break-word;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
    }
    .timeRow{
        height:50px;
        margin:0 auto;
        position: relative;
        border-bottom:2px solid #ffffff;
    }
    .timeCol{
        width:2px;
        height:4px;
        position: absolute;
        bottom:0;
        background:#ffffff;

    }
    .timeText{
        position: absolute;
        bottom:0;
        left:0;
        transform-origin: left bottom;
        transform:rotateZ(-45deg);
        color:#ffffff;
    }
    .table_header_box{
        width:120px;
        border-bottom:2px solid #ffffff;
        border-radius:6px;
        background:#0d8cdd;
        text-align: center;
        position: relative;
        color:#ffffff;
    }
    .room_name{
        position: absolute;
        width:100%;
        top:50%;
        left:0;
        transform: translateY(-50%);
        display: -webkit-box;
        overflow: hidden;
        white-space: normal;
        text-overflow: ellipsis;
        word-wrap: break-word;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
    }
    
</style>

 

发表评论

0/200
225 点赞
0 评论
收藏