vue日历日程组件

要求:开发一个日历日程组件:包含回到今天、选择年度、选择月份及日期切换等功能,数据为静态数据。

效果:

 

 

代码:

<template>
  <div class="calendar-container">
    <div class="schedule-head">
      <div class="today" @click="toToday">回到今天</div>
      <div class="select one">
        <el-select class="select" v-model="yearModel" @change="yearChange" placeholder="">
          <el-option v-for="item in years" :key="item.value" :label="item.label" :value="item.value"></el-option>
        </el-select>
      </div>
      <div class="select two">
        <el-select v-model="monthModel" @change="monthChange" placeholder="">
          <el-option v-for="item in months" :key="item.value" :label="item.label" :value="item.value"></el-option>
        </el-select>
      </div>
    </div>
    <div class="weekdays">
      <div class="item" v-for="(item,index) in weekdays" :key="index">{{item}}</div>
    </div>
    <div class="days">
      <div class="days-item" 
        v-for="(item,index) in days" 
        :key="index" 
        @click="daySelect(item)">
        <div class="days-con" v-if="item.year == yyyy && item.month == mm && item.name == dd" :class="item.name == dd ? 'now': ''">
          {{item.name}}
          <div class="circle" v-if="item.content"></div>
        </div>
        <div class="days-con" v-else :class="item.name === currentDay ? 'select': ''">
          {{item.name}}
          <div class="circle" v-if="item.content"></div>
        </div>
      </div>
    </div>
    <div class="schedule-list">
      <div class="title">日程安排</div>
      <div v-if="scheduleList && scheduleList.length" class="schedule">
        <div class="schedule-item">
          <el-timeline>
            <el-timeline-item class="line-item" 
              v-for="(item,index) in scheduleList" 
              :key="index"
              color="#ffffff"
              size="large">
              <div class="time">{{item.time}}</div>
              <div class="circle">
                <div>{{item.type == 1 ? '会议': ''}}</div>
              </div>
              <div class="content">
                <div class="name">{{item.name}}</div>
                <div class="site">
                  <img class="icon" src="../assets/img/locate.png">
                  <span>{{item.place}}</span>
                </div>
                <div class="people">
                  <div class="txt" @click="openDia(item.people)">查看参与者</div>
                  <div class="num">(共{{item.num}}人)</div>
                </div>
              </div>
            </el-timeline-item>
          </el-timeline>
        </div>
      </div>
      <div v-else class="no-data">暂无安排!</div>
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      yyyy: null,
      mm: null,
      dd: null,
      yearModel: null,
      monthModel: null,
      years: [],
      months: [],
      weekdays:['周日','周一','周二','周三','周四','周五','周六'],
      days: [],
      today: null, //今天
      currentDay: null, // 选中天
      scheduleList: [],
      tableDate:[
        {year:2021,month:12,name:2,content:[
          {time:'10:00 - 11:00',type: 1,name:'2会议名称会议名称会议会议名称会议会议名称会议会议名称会议会议名称会议会议名称会议会议名称会议名称会议名称会议名称会议名称会议名称',place:'小会议室',people:'张三、李四、王五',num:'3'},
          {time:'14:00 - 16:00',type: 1,name:'2会议名称',place:'小会议室',people:'张三、李四',num:'2'},
          {time:'16:20 - 16:50',type: 1,name:'2会议名称',place:'小会议室',people:'张三、李四',num:'2'},
          {time:'17:00 - 18:00',type: 1,name:'21会议名称',place:'小会议室',people:'张三、李四',num:'2'},
        ]},
        {year:2021,month:12,name:5,content:[
          {time:'10:00 - 11:00',type: 1,name:'5会议名称会议名称会议会议名称会议会议名称会议会议名称会议会议名称会议会议名称会议会议名称会议名称会议名称会议名称会议名称会议名称',place:'小会议室',people:'张三、李四、王五',num:'3'},
          {time:'14:00 - 16:00',type: 1,name:'5会议名称',place:'小会议室',people:'张三、李四',num:'2'},
          {time:'16:20 - 16:50',type: 1,name:'5会议名称',place:'小会议室',people:'张三、李四',num:'2'},
          {time:'16:20 - 16:50',type: 1,name:'5会议名称',place:'小会议室',people:'张三、李四',num:'2'},
        ]},
        {year:2021,month:12,name:14,content:[
          {time:'10:00 - 11:00',type: 1,name:'14会议名称会议名称会议会议名称会议会议名称会议会议名称会议会议名称会议会议名称会议会议名称会议名称会议名称会议名称会议名称会议名称',place:'小会议室',people:'张三、李四、王五',num:'3'},
          {time:'14:00 - 16:00',type: 1,name:'14会议名称',place:'小会议室',people:'张三、张三、李四张三、李四张三、李四张三、李四张三、李四张三、李四李四',num:'2'},
          {time:'16:20 - 16:50',type: 1,name:'14会议名称',place:'小会议室',people:'张三、李四',num:'2'},
          {time:'16:20 - 16:50',type: 1,name:'14会议名称',place:'小会议室',people:'张三、李四',num:'2'},
        ]},
        {year:2021,month:12,name:15,content:[
          {time:'10:00 - 11:00',type: 1,name:'15会议名称会议名称会议会议名称会议会议名称会议会议名称会议会议名称会议会议名称会议会议名称会议名称会议名称会议名称会议名称会议名称',place:'小会议室',people:'张三、李四、王五',num:'3'},
          {time:'14:00 - 16:00',type: 1,name:'15会议名称',place:'小会议室',people:'张三、李四',num:'2'},
          {time:'16:20 - 16:50',type: 1,name:'15会议名称',place:'小会议室',people:'张三、李四',num:'2'},
          {time:'16:20 - 16:50',type: 1,name:'15会议名称',place:'小会议室',people:'张三、李四',num:'2'},
        ]},
        {year:2021,month:12,name:22,content:[
          {time:'10:00 - 11:00',type: 1,name:'22会议名称会议名称会议会议名称会议会议名称会议会议名称会议会议名称会议会议名称会议会议名称会议名称会议名称会议名称会议名称会议名称',place:'小会议室',people:'张三、李四、王五',num:'3'},
          {time:'14:00 - 16:00',type: 1,name:'22会议名称',place:'小会议室',people:'张三、李四',num:'2'},
          {time:'16:20 - 16:50',type: 1,name:'22会议名称',place:'小会议室',people:'张三、李四',num:'2'},
          {time:'16:20 - 16:50',type: 1,name:'22会议名称',place:'小会议室',people:'张三、李四',num:'2'},
        ]},
        {year:2022,month:1,name:4,content:[
          {time:'10:00 - 11:00',type: 1,name:'4会议名称会议名称会议会议名称会议会议名称会议会议名称会议会议名称会议会议名称会议会议名称会议名称会议名称会议名称会议名称会议名称',place:'小会议室',people:'张三、李四、王五',num:'3'},
          {time:'14:00 - 16:00',type: 1,name:'4会议名称',place:'小会议室',people:'张三、李四',num:'2'},
          {time:'16:20 - 16:50',type: 1,name:'45会议名称',place:'小会议室',people:'张三、李四',num:'2'},
          {time:'16:20 - 16:50',type: 1,name:'4会议名称',place:'小会议室',people:'张三、李四',num:'2'},
        ]},
        {year:2022,month:1,name:7,content:[
          {time:'10:00 - 11:00',type: 1,name:'7会议名称会议名称会议会议名称会议会议名称会议会议名称会议会议名称会议会议名称会议会议名称会议名称会议名称会议名称会议名称会议名称',place:'小会议室',people:'张三、李四、王五',num:'3'},
          {time:'14:00 - 16:00',type: 1,name:'7会议名称',place:'小会议室',people:'张三、李四',num:'2'},
          {time:'16:20 - 16:50',type: 1,name:'7会议名称',place:'小会议室',people:'张三、李四',num:'2'},
          {time:'16:20 - 16:50',type: 1,name:'7会议名称',place:'小会议室',people:'张三、李四',num:'2'},
        ]},
        {year:2022,month:1,name:10,content:[
          {time:'10:00 - 11:00',type: 1,name:'10会议名称会议名称会议会议名称会议会议名称会议会议名称会议会议名称会议会议名称会议会议名称会议名称会议名称会议名称会议名称会议名称',place:'小会议室',people:'张三、李四、王五',num:'3'},
          {time:'14:00 - 16:00',type: 1,name:'10会议名称',place:'小会议室',people:'张三、李四',num:'2'},
          {time:'16:20 - 16:50',type: 1,name:'10会议名称',place:'小会议室',people:'张三、李四',num:'2'},
          {time:'16:20 - 16:50',type: 1,name:'10会议名称',place:'小会议室',people:'张三、李四',num:'2'},
        ]},
      ]
    }
  },
  mounted() {
    var date = new Date()
    this.yyyy = date.getFullYear()
    this.mm = date.getMonth() + 1
    this.dd = date.getDate()
    this.initDate()
  },
  methods: {
    getList() {
      const params = {
        year: this.yearModel,
        month: this.monthModel
      }
      this.getMonthDayNum(this.yearModel,this.monthModel)
      console.log(params,'ppp')
    },
    // 获取当前月的天数、当前月第一天是周几
    getMonthDayNum(year, month) {
      let d = new Date(year, month, 0)
      let day = d.getDate()
      for (let i = 1; i <= day; i++) {
        this.days.push({year:year,month:month,name:i})
      }
      d.setDate(1)
      let weekNum = d.getDay()
      for (let j = 0; j < weekNum; j++) {
        this.days.unshift('')
      }
      this.tableDate.forEach((item) => {
        this.days.forEach((d,i) => {
          if(item.year == this.yearModel && item.month == this.monthModel) {
            if(item.name == d.name) {
              this.days[i].content= item.content
            }
          }
        })
      })
      console.log(this.days,'fff')
    },
    // 回到今天
    toToday() {
      this.days = []
      this.yearModel = this.yyyy
      this.monthModel = this.mm
      this.today = this.dd
      this.currentDay = null
      // this.scheduleList = []
      this.tableDate.forEach((item) => {
        if(this.yearModel == item.year && this.monthModel == item.month && this.today == item.name) {
          this.scheduleList = item.content
        }
      })
      this.getMonthDayNum(this.yearModel,this.monthModel)
    },
    // 选中天
    daySelect(val) {
      this.currentDay = val.name
      console.log(val,'vvvvv')
      this.scheduleList = val.content
    },
    initDate() {
      this.yearModel = this.yyyy
      this.monthModel = this.mm
      this.today = this.dd
      this.currentDay = null
      console.log(this.yyyy,this.mm,this.dd,'g')
      this.tableDate.forEach((item) => {
        if(this.yearModel == item.year && this.monthModel == item.month && this.today == item.name) {
          this.scheduleList = item.content
        }
      })
      console.log(this.scheduleList,'ssss')
      this.selectYear(this.yearModel)
      this.selectMonth(this.monthModel)
      this.getMonthDayNum(this.yearModel,this.monthModel)
    },
    // 选择年
    yearChange() {
      this.days = []
      this.scheduleList = []
      this.getList()
    },
    // 选择月
    monthChange() {
      this.days = []
      this.scheduleList = []
      this.getList()
    },
    selectYear(year) {
      this.years = []
      for(let i=0;i<30;i++) {
        this.years.push({value:(year+1-i),label:(year+1-i)+'年'})
      }
    },
    selectMonth() {
      this.months = []
      for(let i=1;i<=12;i++){
        this.months.push({value:i,label:i+ "月"});
      }
    },
    openDia(val) {
      this.$alert(val,'查看参与者', {
        confirmButtonText: '关闭',
        callback: action => {
          console.log(action)
        }
      })
    }
  }
}
</script>
<style lang="scss" scoped>
$w:100vw/1920;
:deep().el-timeline-item__tail {
  position: absolute;
  border-left: 1*$w dashed rgba(242, 141, 73, 1);
}
.calendar-container {
  font-family: SourceHanFont;
  .schedule-head {
    margin-top: 25*$w;
    display: flex;
    justify-content: flex-end;
    align-items: center;
    font-size: 14*$w;
    font-weight: 400;
    .today {
      margin-right: 23*$w;
      cursor: pointer;
      color: #3377FF;
      line-height: 20*$w;
    }
    .select {
      :deep().el-select{
        line-height: 30*$w;

      }
      &.one {
        margin-right: 5*$w;
        :deep().el-input {
          width: 96*$w;
        }
      }
      &.two {
        :deep().el-input {
          width: 80*$w;
        }

      }
    }
  }
  .weekdays {
    display: flex;
    font-size: 14*$w;
    font-weight: 400;
    color: #6484AB;
    line-height: 19*$w;
    margin-top: 19*$w;
    .item {
      width: 77*$w;
      text-align: center;
    }
  }
  .days {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    width: 100%;
    .days-item {
      margin: 8*$w 20*$w 0;
      font-size: 14*$w;
      font-weight: 400;
      color: #6484AB;
      position: relative;
      .days-con {
        width: 36*$w;
        line-height: 36*$w;
        text-align: center;
        cursor: pointer;
        &.now {
          text-align: center;
          width: 36*$w;
          background: #538FFF;
          border-radius: 30*$w;
          color: #fff;
          box-sizing: border-box;
          line-height: 34*$w;
        }
        &.select {
          line-height: 34*$w;
          text-align: center;
          width: 36*$w;
          border-radius: 30*$w;
          background: rgba(83, 143, 255, 0.1);
          border: 1*$w solid #538FFF;
          box-sizing: border-box;
        }
      }
      .circle {
        position: absolute;
        bottom: 2*$w;
        left: 45%;
        width: 5*$w;
        height: 5*$w;
        background: #F28D49;
        border-radius: 50%;
      }
    }
  }
  .schedule-list {
    position: relative;
    .title {
      margin: 20*$w 0 20*$w 10*$w;
      font-size: 16*$w;
      font-weight: 500;
      color: #3D4966;
      line-height: 14*$w;
    }
    .schedule {
      max-height: 480px;
      overflow-y: auto;
      &::-webkit-scrollbar{
        display: none;
      }
    }
    .schedule-item {
      margin: 0 8*$w 0 139*$w;
      font-size: 14*$w;
      font-weight: 400;
      .line-item {
        .time {
          position: absolute;
          left: -120*$w;
          top: 2*$w;
          color: #3D4966;
          line-height: 14*$w;
        }
        .circle {
          position: absolute;
          left: -20*$w;
          top: 2*$w;
          text-align: center;
          background: #fff;
          color: #F28D49;
          line-height: 20*$w;
          z-index: 99;
          div {
            border-radius: 10*$w;
            width: 50*$w;
            background: rgba(242, 141, 73, .11);
          }
        }
        .content {
          margin-left: 20*$w;
          .name {
            width: 351*$w;
            color: #3D4966;
            line-height: 18*$w;
            display: -webkit-box;
            -webkit-box-orient: vertical;
            -webkit-line-clamp: 2;
            overflow: hidden;
          }
          .site {
            margin: 8*$w 0 10*$w;
            color: #6484AB;
            line-height: 18px;
            .icon {
              width: 10*$w;
              height: 14*$w;
              margin-right: 6*$w;
            }
          }
          .people {
            color: #3377FF;
            line-height: 14*$w;
            display: flex;
            align-items: center;
            cursor: pointer;
            .num {
              margin-left: 10*$w;
              color: #6484AB;
            }
          }
        }
      }
    }
    .no-data {
      margin: 22*$w;
      text-align: center;
      height: 48*$w;
      font-size: 22*$w;
      
      font-weight: 400;
      color: #CDDAEA;
      line-height: 20*$w;
    }
  }
}
</style>

  • 7
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值