vue+element UI的 table组件实现日历

有现成的日历插件但是不符合需求,所以项目中使用vue+element 的表格组件自己实现一个日历组件
核心js部分:此部分为计算的当月的日期且包含是否可选,是否节假日等等可操作的标记,这部分基本是实现日历的核心部分

        _getRegionData(startDateOfMonth, endDateOfMonth, startDate, endDate) {
            const region = endDateOfMonth.diff(moment(startDateOfMonth), 'days') + 1 //42
            startDate = moment(startDate).format('YYYY-MM-DD')
            let regionArr = [],
              i = 0
            while (i < region) {
              const time = moment(startDateOfMonth)
                .add(i, 'day')
                .format('YYYY-MM-DD')
              const isShow = moment(time).isSame(startDate)
                ? true
                : moment(time).isSame(endDate)
                ? true
                : moment(time).isAfter(startDate) && moment(time).isBefore(endDate)
              const isHistory=moment(time).diff(moment(new Date()).format("YYYY-MM-DD")) < 0?true:false
              regionArr.push({
                time,
                isChoose: false,
                isShow,
                isHoliday:false, // 是否显示
                isHistory, // 是否为历史日期
              })
              i++
            }
            return regionArr
          },
          _ajaxEditData(regionArr) {
            // const {holiday} = this.NurseryClass      
            // const {class_day} = this.NurseryClass.classOptObj
            const holiday ='2021-03-8'
     
            regionArr.forEach(item => {
              if(holiday.indexOf(item.time)!== -1) {
                item.isHoliday = true
              }
             
              
            })
            return regionArr
          },
          _handleData(regionAjaxArr, endDate) {
            // 截取数据 星期一到星期天
            let tableData = [],
              region = 6,
              i = 0,
              tableDataRes = []
            while (i < region) {
              tableData.push(regionAjaxArr.slice(7 * i, 7 + 7 * i))
              i++
            }
            // 组装数据 0:{Mon: {…}, Tue: {…}, Wed: {…}, Thu: {…}, Fri: {…}
            tableData.forEach((item, index) => {
              tableDataRes[index] = {}
              item.forEach((ele, eleIndex) => {
                tableDataRes[index][this.weekKeys[eleIndex]] = ele
              })
            })
            // 判断最后一 二行数据
            let diffIndex = []
            tableDataRes.forEach((item, index) => {
              let isFlag = false
              Object.keys(item).forEach(week => {
                if (item[week]['isShow']) {
                  isFlag = true
                }
              })
              if (!isFlag) {
                diffIndex.push(index)
              }
            })
            // 删除空的两行
            diffIndex.length && tableDataRes.splice(-diffIndex.length)
            return tableDataRes
          },
          // 初始化当前月份的开始日期和结束日期
          _initStartEnd(startDate) {
            // 当月1号
            var currMonth = moment(startDate, 'YYYY-MM'),
              // 当月1号是周几 the ISO day of the week with 1 being Monday and 7 being Sunday.
              firstDay_weekday = currMonth.isoWeekday(),
              startDateOfMonth,
              endDateOfMonth,
              // 开始为周日
              dayStartFromSunday = moment(startDate).format('d') === 0
            // 开始为周日 则直接向前周几的天数即可
            // 开始为周一 则向前减少周几的天数-1即为 开始的日期
            // console.log(firstDay_weekday)
            startDateOfMonth = currMonth.subtract(
              dayStartFromSunday ? firstDay_weekday : firstDay_weekday - 1,
              'day'
            )
            endDateOfMonth = startDateOfMonth.clone().add(41, 'day')
            return [startDateOfMonth, endDateOfMonth]
          },
          _initData(startDate) {
            // const startDate = '2019-02-01'
           
            const endDate = moment(startDate).endOf('month')
            // 起始时间 - 结束时间 42天
            const [startDateOfMonth, endDateOfMonth] = this._initStartEnd(startDate)
            // 获取区间数据 {time: "2019-01-28", isChoose: false}
            const regionArr = this._getRegionData(
              startDateOfMonth,
              endDateOfMonth,
              startDate,
              endDate
            )
            // ajax 数据修改 {time:,isChoose:true}
            const regionAjaxArr = this._ajaxEditData(regionArr)          
            // 组装 {Mon: {…}, Tue: {…}, Wed: {…}, Thu: {…}, Fri: {…}
            const data = this._handleData(regionAjaxArr, endDate)
            console.log(data)
            this.dateTable=data
            // this.SETOPTIONS({setclassTime:true})  
          },

data部分

  data() {
    return {
        nowMonth:'',
        dateTable:[],
      tableKey:[
  { key: 'Mon', label: '一', width: 90 },
  { key: 'Tue', label: '二', width: 90 },
  { key: 'Wed', label: '三', width: 90 },
  { key: 'Thu', label: '四', width: 90 },
  { key: 'Fri', label: '五', width: 90 },
  { key: 'Sat', label: '六', width: 90 },
  { key: 'Sun', label: '日', width: 90 }
],
 weekKeys:['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
 allWeek: false,
      allWeekends: false,
      disabledAll: false,
      loadingText: "",
      class_day: [],
      pickerOptions: {
        disabledDate: (time) => {
            //此部分为对可选月份进行最大月份控制
        //   const { maxDate, minDate } = this.NurseryClass;
        //   if (maxDate) {
            // return (
            //   moment(maxDate) < time.getTime() ||
            //   time.getTime() < moment(minDate)
            // );
        //   } else {
        //     return time.getTime() < moment(minDate);
        //   }
        },
      },
      
      classOptObj:{}
    };
  },
  filters: {
    timeFilter(time) {
      return Number(time.slice(-2));
    },
  },
  created(){
  this._initData('2021-03')
  },

HTML部分:此部分对节日和是否可排课做了处理,也可根据自己业务需要修改

  <div class="festival-holiday-table _table">
    <div class="_title">
      <div class="qiehuan">
        <span @click="change(0)" class="changeM">
          <i class="el-icon-arrow-left"></i
        ></span>
        <el-date-picker
          v-model="nowMonth"
          type="month"
          value-format="yyyy-MM"
          :editable="false"
          :clearable="false"
          @change="changeM"
          placeholder="选择月"
          size="mini"
          style="width: 120px"
          :picker-options="pickerOptions"
        >
        </el-date-picker>
        <span @click="change(1)" class="changeM"
          ><i class="el-icon-arrow-right"></i
        ></span>
      </div>
      <div class="allcheck">
        <el-checkbox
          v-model="allWeek"
          :disabled="allWeek || disabledAll"
          @change="_allWeek"
          >本月周中全选</el-checkbox
        >
        <el-checkbox
          v-model="allWeekends"
          :disabled="allWeekends || disabledAll"
          @change="_allWeekends"
          >本月周末全选</el-checkbox
        >
      </div>
    </div>

    <el-table
      :data="dateTable"
      border
      style="width: 80%;margin:100px auto; "
      
    >
      <el-table-column
        v-for="item in tableKey"
        :key="item.key"
        :prop="item.key"
        :label="item.label"
        align="center"
      >
        <template slot-scope="scope" v-if="scope.row[item.key].isShow">
          <section
            v-if="scope.row[item.key].isHistory"
            @click="_restToggle(scope.row, [item.key])"
            class="table-item isHistory"
            :class="{ 'table-item-rest': scope.row[item.key].isChoose }"
          >
            <span>{{ scope.row[item.key].time | timeFilter }}</span>
            <span class="item-rest" v-if="scope.row[item.key].isChoose"
              >课</span
            >
            <span class="item-holiday" v-if="scope.row[item.key].isHoliday"
              >节日</span
            >
          </section>
          <section
            v-else
            @click="_restToggle(scope.row, [item.key])"
            class="table-item"
            :class="{ 'table-item-rest': scope.row[item.key].isChoose }"
          >
            <span>{{ scope.row[item.key].time | timeFilter }}</span>
            <span class="item-rest" v-if="scope.row[item.key].isChoose"
              >课</span
            >
            <span class="item-holiday" v-if="scope.row[item.key].isHoliday"
              >节日</span
            >
          </section>
        </template>
      </el-table-column>
    </el-table>
    </div>
css部分:
<style lang='scss' scoped>
/deep/.el-table--scrollable-x /deep/.el-table__body-wrapper {
  overflow: inherit;
}

.festival-holiday-table {
  margin: 0 auto;
  padding: 20px 20px 0 20px;
  padding-top: 0;
  font-size: 12px;
  color: #606266;
  background-color: #fff;
.isHistory{
  background-color: #f5f7fa;
}
  .table-item {
    padding: 20px;
    cursor: pointer;
    position: relative;
    color: #000;
    font-size: 14px;

    .item-holiday {
      position: absolute;
      right : 0;
      bottom: 0;
      width: 30px;
      height: 20px;
      box-sizing: border-box;
      background: red;
      line-height: 20px;
      font-size: 13px;
      color: #ffffff;
    }

    .item-rest {
      position: absolute;
      left: 0;
      top: 0;
      width: 20px;
      height: 20px;
      box-sizing: border-box;
      background: #03a9f4;
      line-height: 20px;
      font-size: 13px;
      color: #ffffff;
    }
  }
}

.tishi {
  display: flex;
  margin-top: 13px;

  p {
    flex: 1;
  }
}
._title{
  display: flex;
  position: relative;
}
.qiehuan {
  margin-bottom: 15px;
}
.allcheck{
position: absolute;
right: 0;
}
.changeM {
  cursor: pointer;
  color: #03a9f4;
}

._content {
  text-align: center;
  margin-bottom: 10px;
}
</style>
<style >
.festival-holiday-table._table
  .el-table--enable-row-hover
  .el-table__body
  tr:hover
  > td {
  background: none;
}
.festival-holiday-table._table .el-table td {
  padding: 0 !important;
}
.festival-holiday-table._table .el-table .cell {
  padding: 0;
}

#Ms_table .el-table th,
._table .el-table th {
  background-color: #03a9f4;
  color: #333;
  border-color: #909399;
}
</style>

以上是整个代码,其主要部分是js获取数据部分,其他都相对容易,可根据实际业务情况进行修改

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值