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
- 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)
- Content of the month and style of the day
- 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:
- Regular day
- today
- 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