A brief introduction to this component automatically generates a calendar for the last month, corresponding to the date and week, and adds click events to the desired dates.

Okk directly to the code: since it is written on the mobile terminal, the pixel unit is REM, 1REM = 75px;

<template>
    <div class="calendar-container">
        <div class="c-header">
            <div class="c-h-left">
                <span></span>
                <div class="time">{{lastMonth}}</div>
            </div>
            <div class="c-h-right">
                <div class="top">The calendar</div>
                <div class="month_en">{{monthEn}}</div>
            </div>
        </div>
        <div class="c-center">
            <div class="c-c-header">
                <div v-for="(item, index) in headerList" :key="index" :class="{'c-weekend-item':index > 4}" class="c-h-item">{{item}}</div>
            </div>
            <div class="c-c-body">
                <div v-for="(item, index) in bodyList" :key="index" @click="hasClick(item)? showModal(item):''" :class="{'c-weekend-item':index%7 === 6 || index%7 === 5, 'c-item-click' : hasClick(item)}" class="c-b-item">
                    <div class="item">{{item}}</div>
                    <span v-if="hasClick(item)" class="clickIcon"><span></span></span>
                </div>
            </div>
        </div>
        <div class="c-footer">
            
        </div>
    </div>
</template>

<script>
   export default {
      name: "calendar".data() {
         return {
            time: '2021-12-31'.lastMonth: '2021/03'.monthEn: 'MARCH'.headerList: ['MO'.'TU'.'WE'.'TH'.'FR'.'SA'.'SU'].bodyList: [].calendar: [{date: "2021-04-18".val: 18}, {date: "2021-04-22".val: 22,},]}},mounted() {
           this.getData();
        },
        methods: {
           // Check whether the current date has a click time
           hasClick(data) {
              let status = false;
              this.calendar.forEach((item) = > {
                  if (item.val == data) {
                      status = true; }});return status;
           },
           // Display the popbox
	   showModal(item) {
               console.log(item);
               // do something...
           },
           // Data processing
           getData() {
               let dateInfo = this.getLastMonthEndTime();
                this.lastMonth = dateInfo.lastMonth;
                let i = 1;
                while (i < (dateInfo.week === 0 ? 7 : dateInfo.week)) {
                   this.bodyList.push(' ');
                   i++;
                }
                let j = 1;
                while (j <= dateInfo.endData) {
                   this.bodyList.push(j); j++; }},// Get the end time of last month/week of 1st/time of last month
           getLastMonthEndTime() {
              let myDate = new Date(a);let year = myDate.getFullYear();
              let month = myDate.getMonth();
              if (month === 0) {
                 month = 12;
                 year = year - 1;
              } else if (month < 10) {
                 month = '0' + month;
              }
              let monthDate = new Date(year, month, 0);
              let beginTime = year + The '-' + month + '- 01';
              // let endTime = year + '-' + month + '-' + monthDate.getDate();
              let data = {
                 endData: monthDate.getDate(),
                 week: new Date(beginTime).getDay(),
                 lastMonth: year + '/' + month,
                };
              return data
           },
        }
   }
</script>

<style scoped lang="less">
    .calendar-container {
        width: 100%;
        height: 100%;
        border: 0.01 rem solid # 999999;
        border-top: 0.08 rem solid # 333;
        border-bottom: 0.08 rem solid # 333;

        .c-header {
            height: 1.5 rem;
            border-bottom:.01rem solid # 999999;
            overflow: hidden;
            padding: 0 0.40 rem;

            .c-h-left {
                float: left;
                height: 100%;
                position: relative;

                .time {
                    height: 100%;
                    line-height: 1.5 rem;
                    font-size: 0.56 rem;
                    font-weight: bold;
                    font-style: italic;
                    color: # 333333;
                    position: relative;
                }

                span {
                    width: 0.67 rem;
                    height: 0.27 rem;
                    background: rgba(202.173.255.1);
                    position: absolute;
                    right: -.04rem;
                    bottom:.45rem; }}.c-h-right {
                float: right;
                text-align: right;
                padding-top: 0.34 rem;

                .top {
                    line-height: 1;
                    font-size: 0.32 rem;
                    font-weight: 400;
                    color: # 333333;
                    margin-bottom:.08rem;
                }

                .month_en {
                    line-height: 1;
                    font-size: 0.43 rem;
                    font-weight: bold;
                    color: # 333333; }}}.c-center {
            min-height: 4.23 rem;
            width: 100%;
            overflow: hidden;
            text-align: center;
            padding: 0.67 rem;

            .c-c-header {
                width: 100%;
                overflow: hidden;

                .c-h-item {
                    width: 14%;
                    float: left;
                    font-size: 0.39 rem;
                    font-weight: 400;
                    color: # 000000; }}.c-c-body {
                width: 100%;
                overflow: hidden;

                .c-b-item {
                    width: 14%;
                    height: 0.67 rem;
                    line-height:.67rem;
                    float: left;
                    font-size: 0.39 rem;
                    font-weight: 400;
                    color: #4A4A4A;
                    margin-top: 0.20 rem;
                    position: relative;

                    .item {
                        position: relative;
                        z-index: 1;
                    }

                    .clickIcon {
                        display: block;
                        width: 0.67 rem;
                        height:.67rem;
                        background: #8372FF;
                        border-radius: 50%;
                        position: absolute;
                        left: 50%;
                        top: 0;
                        transform: translateX(-.33rem);
                        z-index: 0;

                        span {
                            display: block;
                            width: 0.21 rem;
                            height: 0.21 rem;
                            background: #B2A8FF;
                            border-radius: 50%;
                            float: right;
                            margin-top:.46rem; }}}}.c-weekend-item {
                color: #D35362! important;
            }
            
            .c-item-click {
                color: #FFFFFF! important; }}.c-footer {
            height: 0.88 rem;
            line-height: 0.88 rem;
            border-top:.01rem solid # 999999;
            padding: 0 0.24 rem;
            font-size: 0.32 rem;
            font-weight: 400;
            color: # 333333;
            overflow: hidden; }}</style>
Copy the code