I believe that there are many friends and I mentioned the calendar on the skull pain, and then go to the Internet to search for useful calendar components, such as element-UI what, but the calendar is developed by others, and their home UI design function style after all can not be 100% similar, So at this time, either go to Git to find a similar one and modify the code, or you can only develop one by yourself, so I also share the idea of packaging calendar components that I have learned.

I know many people have already written about the calendar component, but I want to write about it.

The preparatory work

I chose to build a new scaffold for development, so I went to vue-CLI official website to pull a new scaffold in the local, I believe everyone should be able to do this. NPM serve starts after successful pull.

Then I get used to writing CSS styles in less, so I’m installing a less and less loader, and then it varies from person to person;

start

I believe that many friends and I do not know how to start after seeing the calendar, how to distinguish the last month and the current month, in fact, after understanding the idea and principle is very simple.

A calendar has 42 days and 35 days, because 6 or 7 lines, 7 lines show more comprehensive; The advantage of 42 days is that it can display all the last month, the current month and the next month. The disadvantage is that the last month and the next month occupy a lot of time, so there is some redundancy. If 35 days are used, it will look simplified.

First we need to look at the day of the week for the first day of the current month, so the first day of May is Wednesday, so we use 42-2.

I created a public JS that put some public methods in it to call in the component; The public js I'm going to call utils.js; GetYearMonthDay is a public method in utils to get the year, month and day; const getYearMonthDay = (date) => {let year = date.getFullYear();
 let month = date.getMonth();
 let day = date.getDate();
 return {year, month, day};
};

computed: {
    visibleCalendar: function () {
        letcalendatArr = []; Get the current year, month, and daylet{year, month, day} = utils.getNewDate(utils.getDate(this.time.year, this.time.month, 1)); Get the first day of the month to get the 2019-5-1letcurrentFirstDay = utils.getDate(year, month, 1); Get the first day of the week to get 3letweekDay = currentFirstDay.getDay(); Subtract the preceding days from the first day of the month to get the number of days from the previous month (the current day is Wednesday, so Monday is the last two days of the previous month).letstartTime = currentFirstDay - (weekDay - 1) * 24 * 60 * 60 * 1000; And then you get all the datesfor (let i = 0; i < 42; i++) {
          calendatArr.push({
            date: new Date(startTime + i * 24 * 60 * 60 * 1000),
            year: year,
            month: month + 1,
            day: new Date(startTime + i * 24 * 60 * 60 * 1000).getDate()
          })
        };
        return calendatArr
    }
}

Copy the code

Then the DOM structure goes v-for the array, and you get an initial calendar

But this is ugly, and we can’t tell which day is last month and which day is next month, so we need to style the previous month to distinguish the current month from the previous month

<ul class="calendar-view clear">
  <li v-for="(item, index) in visibleCalendar" 
    :key="index" 
    class="date-view"
    :class="[ {'notCurrentMonth-class': !isCurrentMonth(item.date)}, {currentDay: isCurrentDay(item.date)}, ]"
    @click="handleClickDay(item, index)"
  >
    <span class="date-day"> {{item.day}} </span> </li> </ul> notCurrentMonth-class Pass in each day and compare it to the current year and return isCurrentMonth (Date) {let {year: currentYear, month: currentMonth} = utils.getYearMonthDay(utils.getDate(this.time.year, this.time.month, 1));
    let {year, month} = utils.getYearMonthDay(date);
    returnCurrentYear == year && currentMonth == month} isCurrentDay (date) {let {year: currentYear, month: currentMonth, day: currentDay} = utils.getYearMonthDay(new Date());
    let {year, month, day} = utils.getYearMonthDay(date);
    return currentYear == year && currentMonth == month && currentDay == day;
}

Copy the code

Then add some of your favorite styles to the class name to happily distinguish the current month from the previous month and today

Now it’s just a matter of switching left and right and clicking today to go back to the current month. Now it’s easy. Let’s write two methods to switch from the previous month

Const getDate = (year, month, day) => {const getDate = (year, month, day) => {returnnew Date(year, month, day); } indata () {
    let {year, month, day} = utils.getYearMonthDay(new Date());
    return{yearMonth: {year, month, day},}} // yearMonth: {year, month, daysetMonth() sets the Month and updates yearMonthhandlePrevMonth () {
    letprevMonth = utils.getDate(this.yearMonth.year,this.yearMonth.month,1); prevMonth.setMonth(prevMonth.getMonth() - 1); this.yearMonth = utils.getYearMonthDay(prevMonth); } // Next month to get the current monthsetMonth() sets the Month and updates yearMonthhandleNextMonth () {
    letnextMonth = utils.getDate(this.yearMonth.year,this.yearMonth.month,1); nextMonth.setMonth(nextMonth.getMonth() + 1); this.yearMonth = utils.getYearMonthDay(nextMonth); } // Click back to today for the same reasonhandleToday () {
    this.yearMonth = utils.getYearMonthDay(new Date());
  }
Copy the code

Is it really, really easy to switch left and right and click back to today’s calendar?

Welcome to gitHub calendar

I put the detailed code upload to my lot, I write some more details on the git, also provides some foreign click event, so outside of the component can be invoked inside some of the ways, it is more convenient to use, if you feel not bad, can go to git to the stars or above is what, thank you for your support, If there is something wrong, please point it out and discuss it together.