• 日程表


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

    写在home.vue文件中了

    <template>
        <div class="homeBox">
            <table>
                <!-- 时间轴 -->
                <tr>
                    <td ><div :style="{2*tableWidth+'px',height:tableHeight+'px'}"></div></td>
                    <td v-for="(item,index) in arrLength" :key="index">
                        <div class="timeWrap" :style="{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="{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="{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-768px){
            .min768{
                display:block;
            }
            .max768{
                display: none;
            }
        }
        @media screen and (min-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="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="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="{(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="{(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',(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>
  • 相关阅读:
    说一说javascript的异步编程
    Flink 整合 Nacos,让 Flink 作业配置动态更新不再是难事
    Flink 整合 Apollo,动态更新 Flink 作业配置
    一文让你彻底了解大数据实时计算引擎 Flink
    《大数据实时计算引擎 Flink 实战与性能优化》新专栏
    滴滴实时计算发展之路及平台架构实践
    Flink 从 0 到 1 学习 —— Flink Data transformation(转换)
    Flink Connector 深度解析
    Flink 从 0 到 1 学习 —— Flink 配置文件详解
    vue-cli3如何配置 eslint 及配合 vscode 自动保存
  • 原文地址:https://www.cnblogs.com/fqh123/p/11704924.html
Copyright © 2020-2023  润新知