Renovation project

CodePen original project

scenario

The dashboard of Mac OS is used as a reference, as follows:

Although short time cannot accomplish so exquisite, but at least function gets about the same, clock and weather were OK, feel more troublesome when doing calendar, go to CodePen search, had such.

The source code migration

The original project on CodePen itself was not too difficult, having to figure out the calendar logic (the original author’s logic) and translate the DOM manipulation in this author’s project into the template manipulation of vUE.

Look at the logic

  1. It is possible to have the last month’s tail before the 1st of the month (if we need to fill all the calendar squares)
  2. Content of the month and style of the day
  3. After the last day of the month, there may also be the beginning of the next month

Corresponding to these three functions in the original project, the original author also has a note:

LastDayOfLastMonth the last day of the last month, so it should be lastDayOfPreviousMonth

FirstDayOfMonth First day of the month

LastDateOfMonth Last day of the month

I is the day of the month that does a do while loop

// If not Sunday but first day of the month
// it will write the last days from the previous month
if ( i == 1 ) {
  html += '<tr>';
  var k = lastDayOfLastMonth - firstDayOfMonth+1;
  for(var j=0; j < firstDayOfMonth; j++) {
    html += '<td class="not-current">' + k + '</td>'; k++; }}Copy the code

Add the last month’s tail to the label of the form on the first day.

// Write the current day in the loop
var chk = new Date(a);var chkY = chk.getFullYear();
var chkM = chk.getMonth();
if (chkY == this.currYear && chkM == this.currMonth && i == this.currDay) {
  html += '<td class="today">' + i + '</td>';
} else {
  html += '<td class="normal">' + i + '</td>';
}
Copy the code

Today, other contents of this month are added regularly, which can be distinguished from the class above.

// If not Saturday, but last day of the selected month
// it will write the next few days from the next month
if ( i == lastDateOfMonth ) {
  var k=1;
  for(dow; dow < 6; dow++) {
    html += '<td class="not-current">' + k + '</td>'; k++; }}Copy the code

On the last day of the month, add the first day of the next month.

Missing, the beginning and end of each line

// If Sunday, start new row
if ( dow == 0 ) {
  html += '<tr>';
}
// If Saturday, closes the row
if ( dow == 6 ) {
  html += '</tr>';
}
Copy the code

Here, because the calendar is a line from Sunday to Saturday, the author judges that the scheme is Sunday and Saturday.

These are the core code above, of course, and next month and last month switch, but is to clear the current calendar again, these can see the source code, not too much logic problems.

Turn the vue

It’s not so difficult to turn, it’s more a change of thinking.

While the original project was directly manipulating the DOM, here we are manipulating the template with data (let’s make a difference), so we need to build an object to hold each “day”.

We declare a calendar array. Since the calendar is made up of several weeks, we’ll call it weeks, and then give each “day” to the object with the following attributes:

{
  / / some day
  label: [string],
  // Is it today
  today: [boolean],
  // Is this month
  current: [boolean],
}
Copy the code

Then our “day” will have these situations:

  1. Regular day
  2. today
  3. Days last month or next month
{
  / / some day
  label: [string],
  // Is this month
  current: true,}Copy the code
{
  / / some day
  label: [string],
  // Is it today
  today: true.// Is this month
  current: true,}Copy the code
{
  / / some day
  label: [string],
}
Copy the code

Next, we replace the HTML in the logic with weeks, tr with week (creating an empty array each time), empty week on Sunday or the first day, close week on Saturday or the last day of the month and let Weeks push the week, loop through, Our month of weeks, weeks, and “days” is done.

The core logic is as follows:

const y = this.year, m = this.month
let d = new Date(a)// First day of the month
  , firstDayOfMonth = new Date(y, m, 1).getDay()
  // Last day of the month
  , lastDateOfMonth = new Date(y, m + 1.0).getDate()
  // Last day of last month
  , lastDayOfPreMonth = m === 0 ? new Date(y - 1.11.0).getDate() : new Date(y, m, 0).getDate()

let week = []

// First of month = days
let i = 1
do {
  let dow = new Date(y, m, i).getDay()

  // Sunday is a separate line
  if(dow === 0) {
    week = []
  }
  // The first day of each month displays the last few days of the month
  else if(i === 1) {
    let k = lastDayOfPreMonth - firstDayOfMonth + 1
    for(let j = 0; j < firstDayOfMonth; j++) {
      let obj = {
        label: k,
      }
      week.push(obj)
      k++
    }
  }

  // Query the same day, highlight processing
  let chk = new Date(a)let chkY = chk.getFullYear()
  let chkM = chk.getMonth()
  if(chkY === this.year && chkM === this.month && i === this.day) {
    week.push({
      label: i,
      / / this month
      current: true.today: true,})// Other regular days of the month
  } else {
    week.push({
      label: i,
      / / this month
      current: true})},// It is closed on Saturdays
  if(dow === 6) {
    this.weeks.push(week)
  }
  // The last day of the month, the first days of the next month are displayed in the same month
  else if(i === lastDateOfMonth) {
    let k = 1
    for(dow; dow < 6; dow++) {
      let obj = {
        label: k,
      }
      week.push(obj)
      k++
    }
    this.weeks.push(week)
  }

  i++
} while(i <= lastDateOfMonth)
Copy the code

Pay attention to New Year’s Eve

The final result