日历组件vue2 + cavans海报

需求:显示日历,可前后点击,并且当月之后的不可点击,生成打卡海报页.当月显示已打卡和可补卡 

图如下 : 

封装成的组件,但是在组件内部操作

<div class="mainBoxcaldar">
          <vuecaldar :textTop="['日','一', '二', '三', '四', '五', '六']"
                     :leavenum="leavenum"
                     :dateList="dateList"
                     v-on:changeMonth="changeDate"
                     :canvasposter="canvasposter"
                     :sundayStart="true"
                     :nextinit="nextinit"
                     @sendDay="sendDay"
                     ref="Calendar"
                     typeid="1">
          </vuecaldar>
        </div>
import vuecaldar from './vuecalendar.vue'

data(){
   return{
      leavenum: 0,  //剩余数量
      dateList: [], //当月打卡状态

    }
},
 components: {
    [Popup.name]: Popup,
    [PopupTitleBar.name]: PopupTitleBar,
    [Button.name]: Button,
    [Icon.name]: Icon,
    [TabBar.name]: TabBar,
    vuecaldar
  },
created () {
    this.scentry = getStorage('scentry')
    this.ossurl = getStorage('ossurl', '')
    this.getossurl = config.cdnurl
    this.empno = getStorage('empno', {}).empno // 业务员工号
    this.suserid = getStorage('u_s', {}).id // 用户的id
    // 获取头像
    this.head = getStorage('u_s').headimg  //业务员头像
    this.nickname = getStorage('empno').empname //业务员名字
    this.userid = getStorage('u_s', {}).id // 用户的id
    this.empnoCard = getStorage('empnoCard', {})
    if (this.empnoCard.headimg) {
      this.head = this.getossurl + this.empnoCard.headimg
    } else {
      this.head = getStorage('u_s').headimg
    }
    const nowTime = new Date()  //获取时间
    let noeTimeYear = nowTime.getFullYear()// 当前年
    let noeTimemonth = nowTime.getMonth() + 1  //当前月
    // 左右点击切换月份
    if (noeTimemonth < 10) {
      noeTimemonth = '0' + noeTimemonth
    }
    this.params = noeTimeYear + '-' + noeTimemonth
  },
methods:{
       // 切换月份 ,data日期
    changeDate (data) {
      const nowTime = new Date()  //获取时间
      let noeTimemonth = nowTime.getMonth() + 1
      // 左右点击切换月份
      if (noeTimemonth < 10) {
        noeTimemonth = '0' + noeTimemonth
      }
      let date = data.split('/')
      if (date[1] < 10) {
        data = date[0] + '-0' + date[1]
      } else {
        data = date[0] + '-' + date[1]
      }
      let test = {
        date: data
      }
      this.monthber = Date.parse(test) / 1000
    },
async canvasposter (data) {
      this.mess()
      // 打卡按钮埋点
      setSensors('ButtonClick', {
        buttonName: '分享打卡海报',
        pageName: '叮咚打卡页',
        pageChannel: '叮咚打卡页',
        pageChannel2: '叮咚打卡'
      })

      Toast.loading('生成中...')
      // 隐藏按钮
      document.getElementsByClassName('wh_left')[0].style.opacity = 0
      document.getElementsByClassName('wh')[0].style.opacity = 0
      // 获取海报图片 
      let res = await makeImg(document.getElementsByClassName('mainBoxcaldar')[0])
      this.canvascaldar = res
      this.isposterpop = true
      if (this.canvascaldar) {
        // this.$nextTick(() => {
        const element = document.getElementById("posterbox");
        setTimeout(() => {
          makeImg(element)
            .then(res => {
              this.showposter = res
              // 行为记录
              let data = {
                suserid: this.userid,
                empno: this.empno,
                otype: '03',
                subOtype: '00',
                btagcode: 'PG',
                stagcode: 'dingdongdaka',
                sno: 'dakahaibao',
                osno: 'dakahaibao',
                remark: '合成打卡日历分享海报'
              }
              insertActionCord(data).then((res) => { })
            })
            .finally(() => {
              document.getElementsByClassName('wh_left')[0].style.opacity = 1
              document.getElementsByClassName('wh')[0].style.opacity = 1
            })
          Toast.hide()
        }, 500)
      }
        
    },
    mess () {
      calendarPosterInfo()
        .then(res => {
          this.posterheadimg = res.data.data.img  //头像框
          this.dkDay = res.data.data.dkDay   //打卡天数
          this.posterbg = res.data.data.poster  //背景图
          this.copywriting = res.data.data.copywriting  //提示话语
        })
    },
nextinit () {
      this.init()
    },
init () {
      // 查看当月打卡数据状态
      getRecord({ date: this.params })
        .then(res => {
          // console.log(res)
          if (res.data.code == 200) {
            this.leavenum = res.data.data.num  //本月剩余可用补卡次数
            this.dateList = res.data.data.dateList  //当月打卡情况
          }
        })
      this.$forceUpdate()
    },
sendDay (value) {
      this.params = value
      this.init()
    },
}

在封装的组件直接操作


<template>
  <div>
    <section class="wh_container">
      <div class="wh_content_all">
        <div class="wh_top_changge">
          <!-- 上一月 -->
          <li @click="PreMonth(myDate,false)">
            <img class="wh_left"
                 :src="getossurl + 'ddzsc/images/dkMedal/left.png'"
                 alt="">
          </li>
          <li class="wh_content_li">{{dateTop}}</li>
          <!-- 分享 -->
          <!-- <li @click="shareMonthhb" >
          <img class="wh" :src="getossurl + 'ddzsc/images/dkMedal/share.png'" alt="">
        </li> -->
          <!-- 点击下一月 -->
          <li @click="NextMonth(myDate,false)">
            <img class="wh"
                 v-show="sharebtn"
                 :src="getossurl + 'ddzsc/images/dkMedal/share.png'"
                 alt="">

            <img class="wh_right"
                 v-show="!sharebtn"
                 :src="getossurl + 'ddzsc/images/dkMedal/right.png'"
                 alt="">

          </li>

        </div>
        <div class="wh_content">
          <div class="wh_content_item"
               v-for="tag in textTop">
            <div class="wh_top_tag">{{tag}}</div>
          </div>
        </div>
        <div class="wh_content">
          <div class="wh_content_item"
               v-for="(item,index) in list"
               @click="clickDay(item,index)">
            <div class="wh_item_date"
                 :style="{'color' : item.date == nowDay ? '#fff' : '','background' : item.date == nowDay ? '#EE9A37' : ''}"
                 :class="[
              { wh_isMark: item.isMark},
              {wh_other_dayhide:item.otherMonth!=='nowMonth'},
              {wh_want_dayhide:item.dayHide},
              {wh_isToday:item.isToday},
              {wh_chose_day:item.chooseDay},
              {nodaka:item.type == '0'},
              {yesdaka:item.type == '1' && item.date != nowDay },
              {buka:item.type == '2' && item.date != nowDay},
              setClass(item)]">{{item.id}}</div>
          </div>
        </div>
      </div>
    </section>
    <!-- 补卡提示 -->
    <md-popup v-model="isbukapop">
      <md-icon @click="isbukapop = false"
               name="close"
               size="lg"
               style="position: absolute;right: 5%;top: 9%;"></md-icon>
      <div class="buka_popbox">
        <!-- 标题 -->
        <div class="buka_tit">补卡</div>
        <div class="buka_readnull"
             v-if="leavenum > 0">
          是否确认消耗1次补卡次数
        </div>
        <div class="buka_read"
             v-else>{{tip}}</div>
        <!-- 内容 -->
        <div class="buka_btnnull"
             v-if="leavenum > 0">
          <div class="daka_true"
               @click="change_gobuka">确认打卡</div>
          <div class="lemesee"
               @click="isbukapop = false">我再想想</div>
        </div>
        <div class="buka_btn"
             v-else
             @click="gotofinish">
          <img class="hasbuka_btn"
               v-if="router != ''"
               :src="getossurl + 'ddzsc/images/dkMedal/gofinsh.png'"
               alt="">
        </div>

      </div>
    </md-popup>

    <!-- 日历中已经打卡海报 -->
    <div v-if="isshowDKpop"
         class="testbox">
      <div class="marks"></div>
      <div class="swiper">
        <img class="candel"
             :src="getossurl+'ddzsc/images/morpunchcard/4@2x.png' "
             @click="candel"
             alt="">
        <swiper :options="swiperTab">
          <swiper-slide class="swibox"
                        v-for="item in showpopimg"
                        :key="item.conthttp">
            <img :src="getossurl+ item.conthttp"
                 v-if="item.conthttp"
                 class="borderr"
                 alt="">
          </swiper-slide>
          <!-- <swiper-slide class="swibox">
            <img src="@/assets/images/newDK/hebeijing.png" alt="">
          </swiper-slide> -->
        </swiper>
        <div v-if="showpopimglength>1"
             class="bottext">滑动查看下一张</div>
      </div>
      <!-- <div class="bottext">滑动查看下一张</div> -->
    </div>

  </div>
</template>
<script>
import timeUtil from "./calendar";
import config from '@/config'
import {
  getImg,
  makeCard,
  questInfo,
} from '@/api/abt/customerOperation/morpunchcard/index'
import { setSensors, } from '@/lib/util'
import { selectListkG } from '@/api/abt/unifiedinterface/index'
import { Toast } from 'mand-mobile'
import { swiper, swiperSlide } from 'vue-awesome-swiper'
import 'swiper/dist/css/swiper.css'
export default {
  data () {
    return {
      myDate: [],
      list: [],
      historyChose: [],
      dateTop: "",
      sharebtn: false,
      newnew: 0,
      newmonth: 0,
      getossurl: '',
      nowDay: '',
      isbukapop: false, //补卡提示弹窗
      showpopimg: [{
        conthttp: 'ddzs/KJ_Source/DDDK/2024-01-12/DDDK202401122125564751745799271959035906.png',
        created: '2024-01-12 21:25:56',
        dkType: 'night'
      }],  //已打卡海报弹窗
      clicknowday: '', // 点击的年月日
      thisToday: '', // 当天
      router: '532156', //补卡任务地址 为空表示没有可做任务次数
      tip: '', // 补卡弹窗提示语
      isshowDKpop: false,  //已打卡,
      swiperTab: {
        slidesPerView: 'auto',
        centeredSlides: true,
        spaceBetween: 20,
        pagination: {
          el: '.swiper-tab',
          clickable: true
        },
        observer: true
      },
      showpopimglength: 0,
    };
  },
  components: {
  },
  props: {
    nextinit: {
      type: Function,
    },
    leavenum: {
      type: Number,
    },
    dateList: {
      type: Array,
    },
    typeid: {
      type: String,
    },
    markDate: {
      type: Array,
      default: () => []
    },
    markDateMore: {
      type: Array,
      default: () => []
    },
    textTop: {
      type: Array,
      default: () => ["一", "二", "三", "四", "五", "六", "日"]
    },
    sundayStart: {
      type: Boolean,
      default: () => false
    },
    agoDayHide: {
      type: String,
      default: `0`
    },
    futureDayHide: {
      type: String,
      default: `2554387200`
    },
    canvasposter: {
      type: Function,
    }
  },
  created () {
    this.intStart();
    this.myDate = new Date();
    this.getossurl = config.cdnurl;
    // 获取当天时间
    let currentYear = this.myDate.getFullYear();
    let year = this.myDate.getMonth() + 1
    let day = this.myDate.getDate()
    this.nowDay = currentYear + '/' + year + '/' + day
  },
  methods: {

    candel () {
      this.isshowDKpop = false
      setSensors('AppAllClick', {
        ClickName: '弹窗-关闭',
        input_item: '弹窗',
        pageName: '打卡海报弹窗页',
        pageChannel: '叮咚首页',
        pageChannel2: '叮咚打卡'
      })
    },
    // 去完成按钮
    gotofinish () {
      if (this.router) {
        //  判断接口返会的路由参数是否为空  携带该路由去跳转 this.router
        // generalSkin/skinhome?flush=true
        this.$router.push(this.router)
      } else {
        console.log('没有补卡次数');
      }
    },
    // 确认打卡
    change_gobuka () {
      // 传点击的年月日
      // const formattedDate = this.clicknowday.replace(/\//g, "-");
      // console.log(this.clicknowday)
      // return
      makeCard({ date: this.clicknowday })
        .then(res => {
          if (res.data.code == 200) {
            Toast({
              content: '补卡成功',
              icon: 'right',
              duration: '1000'
            })
            this.isbukapop = false
          }
        })
        .finally(() => {
          this.nextinit()
        })
    },
    intStart () {
      timeUtil.sundayStart = this.sundayStart;
      let currentDate = new Date();
      let currentYear = currentDate.getFullYear();
      // 获取下一个月的日期对象
      let nextMonthDate = timeUtil.getOtherMonth(currentDate, 'nextMonth')
      if (currentYear === nextMonthDate.getFullYear() && (currentDate.getMonth() + 1) === (nextMonthDate.getMonth())) {
        this.sharebtn = true
      } else {
        this.sharebtn = false
      }
    },
    setClass (data) {
      let obj = {};
      obj[data.markClassName] = data.markClassName;
      return obj;
    },
    clickDay: async function (item, index) {
      this.clicknowday = item.date //保存当天日期
      if (this.typeid == '1') {
        // if (item.date == this.thisToday) return  //点击当天
        // 已打卡
        if (item.type == '1' && item.sign == '1') {
          getImg({ param: item.date })
            .then(res => {
              this.showpopimg = res.data.data
              this.showpopimglength = this.showpopimg.length
              setSensors('ButtonClick', {
                buttonName: '点击-已打卡日期',
                pageName: '打卡统计页',
                pageChannel: '叮咚首页',
                pageChannel2: '叮咚打卡'
              })
              setSensors('AppOtherPage', {
                key_word: item.date + '打卡海报',
                pageName: '打卡海报弹窗页',
                pageChannel: '叮咚首页',
                pageChannel2: '叮咚打卡',
                input_item: '弹窗'
              })
            })
          this.isshowDKpop = true
        } else if (item.type == '2') {
          // 今天
          if (!item.isToday) {
            // 有没有补卡机会
            if (this.leavenum > 0) {
              // 有次数//是否确认消耗1次补卡次数补卡
              this.isbukapop = true
            } else {
              // 没次数
              // 先查看跳转地址与回显内容
              let res = await questInfo({ date: this.clicknowday })
              this.tip = res.data.data.tip  //提示语
              res.data.data.router ? this.router = res.data.data.router : this.router = ''//跳转路由
              this.isbukapop = true
            }
          }

        } else {
          // console.log('阿斯利康分到哪是');
        }
      } else {
        if (item.otherMonth === "nowMonth" && !item.dayHide) {
          this.getList(this.myDate, item.date);
        }
      }

    },
    ChoseMonth: function (date, isChosedDay = true) {
      date = timeUtil.dateFormat(date);
      this.myDate = new Date(date);
      this.$emit("changeMonth", timeUtil.dateFormat(this.myDate));
      if (isChosedDay) {
        this.getList(this.myDate, date, isChosedDay);
      } else {
        this.getList(this.myDate);
      }
    },
    PreMonth: function (date, isChosedDay = true) {
      this.sharebtn = false
      date = timeUtil.dateFormat(date);
      this.myDate = timeUtil.getOtherMonth(this.myDate, "preMonth");
      this.$emit("changeMonth", timeUtil.dateFormat(this.myDate));
      if (isChosedDay) {
        this.getList(this.myDate, date, isChosedDay);
      } else {
        this.getList(this.myDate);
      }

      this.$emit('sendDay', this.sendDate)
    },
    shareMonthhb () {
      console.log('生成海报');
    },
    NextMonth: function (date, isChosedDay = true) {
      date = timeUtil.dateFormat(date);
      let currentDate = new Date();
      let currentYear = currentDate.getFullYear();
      let currentMonth = currentDate.getMonth();

      // 获取下一个月的日期对象
      let nextMonthDate = timeUtil.getOtherMonth(this.myDate, "nextMonth");

      // 隐藏下一月按钮 变成分享
      if (currentYear === nextMonthDate.getFullYear() && nextMonthDate.getMonth() + 1 == currentMonth + 1) {
        this.sharebtn = true
      }
      if (currentYear === nextMonthDate.getFullYear() && (this.myDate.getMonth() + 1) === (nextMonthDate.getMonth())) {
        this.list.forEach(item => {
          if (item.type == 2) {
            item.type = '0'
          }
        })
        this.$nextTick(() => {
          this.canvasposter('分享')
          let indx = this.list.findIndex(item => {
            return item.date == this.thisToday;
          })
          this.list.forEach(item => {
            if (item.otherMonth == "nowMonth") {
              // 不这样写会丢失响应式
              this.$set(item, 'type', '0')  //1 已打卡  0 未打卡 2 可补卡
              this.dateList.forEach((el, index) => {
                if (index <= indx) {
                  this.dateList.forEach((el) => {
                    if (item.date == el.date) {
                      item.type = el.type
                    }
                  })
                }
              })
            }
          })
        })
        return; // 不执行下面的切换逻辑
      }
      // 更新当前日期为下一个月的日期对象
      this.myDate = nextMonthDate;
      this.$emit("changeMonth", timeUtil.dateFormat(this.myDate));
      if (isChosedDay) {
        this.getList(this.myDate, date, isChosedDay);
      } else {
        this.getList(this.myDate);
      }
      this.$emit('sendDay', this.sendDate)
    },
    forMatArgs: function () {
      let markDate = this.markDate;
      let markDateMore = this.markDateMore;
      markDate = markDate.map(k => {
        return timeUtil.dateFormat(k);
      });
      markDateMore = markDateMore.map(k => {
        k.date = timeUtil.dateFormat(k.date);
        return k;
      });
      return [markDate, markDateMore];
    },
    getList (date, chooseDay, isChosedDay = true) {
      const [markDate, markDateMore] = this.forMatArgs();
      this.dateTop = `${date.getFullYear()}年${date.getMonth() + 1}月`;
      this.sendDate = `${date.getFullYear()}/${date.getMonth() + 1}`;
      let arr = timeUtil.getMonthList(this.myDate);

      for (let i = 0; i < arr.length; i++) {
        let markClassName = "";
        let k = arr[i];
        k.chooseDay = false;
        const nowTime = k.date;
        const t = new Date(nowTime).getTime() / 1000;
        //看每一天的class
        for (const c of markDateMore) {
          if (c.date === nowTime) {
            markClassName = c.className || "";
          }
        }
        //标记选中某些天 设置class
        k.markClassName = markClassName;
        k.isMark = markDate.indexOf(nowTime) > -1;
        //无法选中某天
        k.dayHide = t < this.agoDayHide || t > this.futureDayHide;
        if (k.isToday) {
          this.$emit("isToday", nowTime);
        }
        let flag = !k.dayHide && k.otherMonth === "nowMonth";
        if (chooseDay && chooseDay === nowTime && flag) {
          if (this.typeid != '1') {
            this.$emit("choseDay", nowTime);
          }

          this.historyChose.push(nowTime);
          k.chooseDay = true;
        } else if (
          this.historyChose[this.historyChose.length - 1] === nowTime &&
          !chooseDay &&
          flag
        ) {
          k.chooseDay = true;
        }
      }
      this.list = arr;  //拿到当月数据
    }
  },
  mounted () {
    this.getList(this.myDate);
  },
  watch: {
    markDate: {
      handler (val, oldVal) {
        this.getList(this.myDate);
      },
      deep: true
    },
    markDateMore: {
      handler (val, oldVal) {
        this.getList(this.myDate);
      },
      deep: true
    },
    agoDayHide: {
      handler (val, oldVal) {
        this.getList(this.myDate);
      },
      deep: true
    },
    futureDayHide: {
      handler (val, oldVal) {
        this.getList(this.myDate);
      },
      deep: true
    },
    sundayStart: {
      handler (val, oldVal) {
        this.intStart();
        this.getList(this.myDate);
      },
      deep: true
    },
    dateList: {
      handler (val) {
        const today = new Date();
        const year = today.getFullYear(); // 获取年份
        const month = today.getMonth() + 1; // 获取月份(注意月份是从0开始的,需要加1)
        const day = today.getDate(); // 获取日期
        this.thisToday = `${year}/${month}/${day}`;

        let indx = this.list.findIndex(item => {
          return item.date == this.thisToday;
        })
        this.list.forEach(item => {
          // this.$set(item, 'type', '0')
          if (item.otherMonth == "nowMonth") {
            // 不这样写会丢失响应式
            this.$set(item, 'type', '0')  //1 已打卡  0 未打卡 2 可补卡
            // this.$forceUpdate()
            this.dateList.forEach((el, index) => {
              this.dateList.forEach((el) => {
                if (item.date == el.date) {
                  item.type = el.type
                  if (el.sign) {
                    item.sign = el.sign
                  }
                }
              })
            })
          }
        })
        console.log('this.list');
      }
    }
  }
};
</script>
<style scoped>
@media screen and (min-width: 460px) {
  .wh_item_date:hover {
    background: #71c7a5;
    cursor: pointer;
  }
}
* {
  margin: 0;
  padding: 0;
}

.wh_container {
  /* max-width: 410PX; */
  /* margin: auto; */
  /* margin: 0.3rem auto;
    width: 95%;
    border-radius: 0.2rem;
    background-color: #fff; */
  /* border: 1px solid #dfdfdf;
  border-radius: 0.3rem;
  background-color: #fff; */
}

li {
  list-style-type: none;
}
.wh_top_changge {
  display: flex;
  margin: 0.5rem auto;
  /* padding-top: 0.5rem; */
}

.wh_top_changge li {
  cursor: pointer;
  display: flex;
  color: #fff;
  font-size: 18px;
  flex: 1;
  justify-content: center;
  align-items: center;
  height: 47px;
}

.wh_top_changge .wh_content_li {
  cursor: auto;
  flex: 2.5;
}
.wh_content_all {
  font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC',
    'Helvetica Neue', STHeiti, 'Microsoft Yahei', Tahoma, Simsun, sans-serif;
  background-color: #0fc37c;
  width: 100%;
  overflow: hidden;
  padding-bottom: 8px;
}

.wh_content {
  display: flex;
  flex-wrap: wrap;
  padding: 0 3% 0 3%;
  width: 100%;
}

.wh_content:first-child .wh_content_item_tag,
.wh_content:first-child .wh_content_item {
  color: #ddd;
  font-size: 16px;
}

.wh_content_item,
wh_content_item_tag {
  font-size: 15px;
  width: 13.4%;
  text-align: center;
  color: #fff;
  position: relative;
}
.wh_content_item {
  height: 40px;
}

.wh_top_tag {
  width: 40px;
  height: 40px;
  line-height: 40px;
  margin: auto;
  display: flex;
  justify-content: center;
  align-items: center;
}

.wh_item_date {
  /* width: 40PX; */
  /* height: 40PX; */
  width: 0.79rem;
  height: 0.79rem;
  line-height: 40px;
  margin: auto;
  display: flex;
  justify-content: center;
  align-items: center;
}

.wh_jiantou1 {
  width: 12px;
  height: 12px;
  border-top: 3px solid #ffffff;
  border-left: 3px solid #ffffff;
  transform: rotate(-45deg);
}
.wh_left {
  width: 0.22rem;
  height: auto;
}

.wh_jiantou1:active,
.wh_jiantou2:active {
  border-color: #ddd;
}
.wh {
  width: 0.8rem;
  height: auto;
}
.wh_right {
  width: 0.22rem;
  height: auto;
}

.wh_jiantou2 {
  width: 12px;
  height: 12px;
  border-top: 2px solid #ffffff;
  border-right: 2px solid #ffffff;
  transform: rotate(45deg);
}
.wh_content_item > .wh_isMark {
  margin: auto;
  border-radius: 100px;
  background: blue;
  z-index: 2;
}
.wh_content_item .wh_other_dayhide {
  color: #bfbfbf;
}
.wh_content_item .wh_want_dayhide {
  color: #bfbfbf;
}
.wh_content_item .wh_isToday {
  background: yellow;
  border-radius: 100px;
}
.wh_content_item .wh_chose_day {
  background: green;
  border-radius: 100px;
}

.wh_content_item .nodaka {
  background: none;
  color: #a5a5a5;
}
.wh_content_item .yesdaka {
  background: none;
  color: #ee9a37 !important;
}
.wh_content_item .buka {
  background: url('https://gxwx-sit.cpiccdn.com/ddzscs/ddzscs/statics/ ddzsc/images/dkMedal/buka.png');
  background-size: 0.8rem 0.8rem;
  background-repeat: no-repeat;
  font-size: 0 !important;
}
</style>
<style lang="stylus" scoped>
.buka_popbox {
  background-color: #fff;
  width: 7.7rem;
  // height: 6rem;
  border-radius: 0.5em;
}

.buka_tit {
  font-size: 0.5rem;
  font-weight: 600;
  padding: 0.3rem 0;
  width: fit-content;
  margin: 0 auto;
}

.buka_read {
  width: 80%;
  color: #999;
  line-height: 0.5rem;
  font-size: 0.35rem;
  margin: 0.3rem auto 0.5rem;
  letter-spacing: 0.02rem;
  width: fit-content;
  padding: 0 0.8rem;
}

.buka_readnull {
  width: 80%;
  color: #999;
  line-height: 0.5rem;
  font-size: 0.35rem;
  margin: 0.6rem auto 1rem;
  letter-spacing: 0.02rem;
  text-align: center;
}

.buka_btn {
  padding-bottom: 0.5rem;
}

.hasbuka_btn {
  width: 3.4rem;
  height: 1.2rem;
  display: block;
  margin: 0 auto;
}

.buka_btnnull {
  width: 75%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 0 auto;
  padding-bottom: 0.5rem;
}

.daka_true, .lemesee {
  height: 1.2rem;
  width: 2.5rem;
  border-radius: 0.7rem;
  text-align: center;
  line-height: 1.2rem;
}

.daka_true {
  color: #fff;
  background-color: #0783d8;
}

.lemesee {
  color: #fff;
  background-color: #d4d4d4;
}

.testbox {
  width: 100vw;
  height: 100vh;
  position: fixed;
  top: 0;
  left: 0;
  z-index: 999;
}

.marks {
  width: 100vw;
  height: 100vh;
  background-color: black;
  opacity: 0.7;
}

.swiper {
  position: absolute;
  top: 50%;
  width: 100vw;
  transform: translateY(-50%);
  /* height: 100vh; */
}

.swiper-slide {
  width: 80%;
}

.candel {
  margin-left: 82vw;
  margin-bottom: 0.2rem;
  width: 1rem;
  height: auto;
}

.candel img {
  width: 100%;
  height: auto;
}

.borderr {
  border-radius: 0.3rem;
}

.bottext {
  width: 100%;
  height: 2rem;
  text-align: center;
  line-height: 2rem;
  color: #fff;
  font-size: 0.4rem;
}
</style>

这里面是对封装的组件内部代码直接操作,因为之前是好多人封装的代码,传了个typeid=1,这样就代表是自己的组件了.

export default {
    // 当某月的天数
    getDaysInOneMonth(date) {
        const year = date.getFullYear();
        const month = date.getMonth() + 1;
        const d = new Date(year, month, 0);
        return d.getDate();
    },
    // 向前空几个
    getMonthweek(date) {
        const year = date.getFullYear();
        const month = date.getMonth() + 1;
        const dateFirstOne = new Date(year + '/' + month + '/1');
        return this.sundayStart ?
            dateFirstOne.getDay() == 0 ? 0 : dateFirstOne.getDay() :
            dateFirstOne.getDay() == 0 ? 6 : dateFirstOne.getDay() - 1;
    },
    /**
     * 获取当前日期上个月或者下个月
    */
    getOtherMonth(date, str = 'nextMonth') {
        const timeArray = this.dateFormat(date).split('/');
        const year = timeArray[0];
        const month = timeArray[1];
        const day = timeArray[2];
        let year2 = year;
        let month2;
        if (str === 'nextMonth') {
            month2 = parseInt(month) + 1;
            if (month2 == 13) {
                year2 = parseInt(year2) + 1;
                month2 = 1;
            }
        } else {
            month2 = parseInt(month) - 1;
            if (month2 == 0) {
                year2 = parseInt(year2) - 1;
                month2 = 12;
            }
        }
        let day2 = day;
        const days2 = new Date(year2, month2, 0).getDate();
        if (day2 > days2) {
            day2 = days2;
        }
        if (month2 < 10) {
            month2 = '0' + month2;
        }
        if (day2 < 10) {
            day2 = '0' + day2;
        }
        const t2 = year2 + '/' + month2 + '/' + day2;
        return new Date(t2);
    },
    // 上个月末尾的一些日期
    getLeftArr(date) {
        const arr = [];
        const leftNum = this.getMonthweek(date);
        const num = this.getDaysInOneMonth(this.getOtherMonth(date, 'preMonth')) - leftNum + 1;
        const preDate = this.getOtherMonth(date, 'preMonth');
        // 上个月多少开始
        for (let i = 0; i < leftNum; i++) {
            const nowTime = preDate.getFullYear() + '/' + (preDate.getMonth() + 1) + '/' + (num + i);
            arr.push({
                id: num + i,
                date: nowTime,
                isToday: false,
                otherMonth: 'preMonth',
            });
        }
        return arr;
    },
    // 下个月末尾的一些日期
    getRightArr(date) {
        const arr = [];
        const nextDate = this.getOtherMonth(date, 'nextMonth');
        const leftLength = this.getDaysInOneMonth(date) + this.getMonthweek(date);
        const _length = 7 - leftLength % 7;
        for (let i = 0; i < _length; i++) {
            const nowTime = nextDate.getFullYear() + '/' + (nextDate.getMonth() + 1) + '/' + (i + 1);
            arr.push({
                id: i + 1,
                date: nowTime,
                isToday: false,
                otherMonth: 'nextMonth',
            });
        }
        return arr;
    },
    // format日期
    dateFormat(date) {
        date = typeof date === 'string' ? new Date(date.replace(/\-/g, '/')) : date;
        return date.getFullYear() + '/' + (date.getMonth() + 1) + '/'
            + date.getDate();
    },
    // 获取某月的列表不包括上月和下月
    getMonthListNoOther(date) {
        const arr = [];
        const num = this.getDaysInOneMonth(date);
        const year = date.getFullYear();
        const month = date.getMonth() + 1;
        const toDay = this.dateFormat(new Date());

        for (let i = 0; i < num; i++) {
            const nowTime = year + '/' + month + '/' + (i + 1);
            arr.push({
                id: i + 1,
                date: nowTime,
                isToday: toDay === nowTime,
                otherMonth: 'nowMonth',
            });
        }
        return arr;
    },
    // 获取某月的列表 用于渲染
    getMonthList(date) {
        return [...this.getLeftArr(date), ...this.getMonthListNoOther(date), ...this.getRightArr(date)];
    },
    // 默认是周一开始
    sundayStart: false,
};

组件日历的方法js文件

点击下个月的方法是NextMonth 

里面处理了对当月的右箭头隐藏变成分享按钮,并且点击分享按钮的时候前端生成海报.图片如下

要求带有补字的不能展示在海报中.所以对海报生成做了处理,隐藏左右按钮和补字样式,生成海报后在对图片做生成.

对makeImg做了封装请求 

官网链接Options | html2canvas

import html2canvas from 'html2canvas'

export const makeImg = function (data) {
  var url = ''
  return new Promise((resolve, reject) => {
    var shareContent = data
    const opts = {
      height: shareContent.offsetHeight - 6,
      width: shareContent.offsetWidth - 1,
      useCORS: true,   //使用CORS从服务器加载图像
      tainttest: true,
      allowTaint: false,   //许跨原点图像污染画布 
      scale: 4  //像素比率
    }
    html2canvas(data, opts).then(function (canvas) {
      // url = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");
      url = canvas.toDataURL('image/png')
      resolve(url)
    })
  })
}

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值