๐Ÿ‘ฉ‍๐Ÿ’ป/Vue

[Vue-todo-list] #1 Date ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•ด ๋‹ฌ๋ ฅ ์ˆซ์ž ๊ตฌํ•˜๊ธฐ/์ง€๋‚œ ๋‚ ์งœ, ์˜ค๋Š˜ ๋‚ ์งœ ๊ตฌ๋ณ„์„ ์œ„ํ•œ CSS ์Šคํƒ€์ผ๋ง

ํ•œ๋‚˜ 2021. 2. 8. 00:41

 

vue.js๋กœ ๋งŒ๋“  ๋‹ฌ๋ ฅ

 

 

๋งจ ์ฒ˜์Œ Vue๋ฅผ ์ ‘ํ–ˆ์„ ๋•Œ ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ๋ณด๋ฉฐ ๋งŒ๋“ค์—ˆ๋˜ To do list ์˜ˆ์ œ๊ฐ€ ์žˆ์—ˆ๋‹ค. ์žŠ๊ณ  ์ง€๋‚ด๋‹ค๊ฐ€ ๋ช‡ ์ฃผ ์ „์— ์ด ์˜ˆ์ œ ์œ„์— TypeScript๋‚˜ CSS framework์ธ Tailwinds ๋“ฑ์„ ๊ณต๋ถ€ํ•ด๋ณด๊ณ  ์‹ถ์–ด์„œ ์ด๊ฒƒ์ €๊ฒƒ ์ƒ๊ฐ์ด ๋‚  ๋•Œ๋งˆ๋‹ค ์‹คํ—˜ํ•˜๋ฉฐ ๋ช‡ ๊ฐœ์˜ ๊ธฐ๋Šฅ์„ ๋ถ™์—ฌ๋‚˜๊ฐ”๋‹ค. ๊ทธ๋Ÿฌ๋‹ค Home ํ™”๋ฉด์ด ๋น„์–ด์„œ ๋ญ˜ ํ• ์ง€ ๊ณ ๋ฏผํ•˜๋‹ค๊ฐ€ JavaScript๋กœ Date ๊ฐ์ฒด๋ฅผ ๋งŽ์ด ์•ˆ ๋‹ค๋ค„๋ด์„œ ์ด ๊ธฐํšŒ์— ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋Œ€์‹  ์ง์ ‘ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ตฌํ˜„ํ•˜๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™์•˜๋‹ค.

 

์ผ๋‹จ ๋‹ฌ๋ ฅ์ฒ˜๋Ÿผ ์ด์ „ ๋‚ ์งœ๋กœ ๋Œ์•„๊ฐ€๊ธฐ, ์ž‘๋…„์ด๋‚˜ ๋‚ด๋…„ ๋“ฑ์œผ๋กœ ์ด๋™ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ–ˆ๋‹ค. ์˜ค๋Š˜ ๋‚ ์งœ๋กœ ๋˜๋Œ์•„์˜ค๋Š” ๋ฒ„ํŠผ๊ณผ ์˜ฌํ•ด์˜ ํŠน์ • ์›”๋กœ ์ด๋™ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ๋„ ๋„ฃ์—ˆ๋‹ค.

 

๋‹ฌ๋ ฅ์— ์˜ค๋Š˜ ๋‚ ์งœ๋ฅผ ํ‘œ์‹œํ•ด์ฃผ๋Š” ๋งˆํฌ๊ฐ€ ๋ถ™๊ณ , to do list์™€ ์—ฐ๊ณ„๋œ ๋‹ฌ๋ ฅ์ด๋‹ˆ ํ•ด๋‹น ๋‚ ์งœ์— ์ƒ์„ฑํ•œ to do๊ฐ€ ์žˆ๋‹ค๋ฉด ํŒŒ๋ž€์ƒ‰ ๋นˆ ์›์œผ๋กœ, ํ•ด๋‹น ๋‚ ์งœ์— ์™„๋ฃŒํ•œ to do๊ฐ€ ์žˆ๋‹ค๋ฉด ์ƒ‰์„ ์ฑ„์šฐ๋„๋ก ๊ฐ„๋‹จํ•˜๊ฒŒ ๊พธ๋ช„๋‹ค.

 

๊ฐ€์žฅ ๋จผ์ € ๋‹ฌ๋ ฅ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๊ธฐ์ค€์ด ๋˜๋Š” ์˜ค๋Š˜ ๋‚ ์งœ ๊ตฌํ•˜๊ธฐ, ๋‹น์›”์˜ 1์ผ์˜ ์š”์ผ, ๋‹น์›”์˜ ๋งˆ์ง€๋ง‰ ๋‚ ์งœ, ์ง์ „ ๋‹ฌ์˜ ๋งˆ์ง€๋ง‰ ๋‚ ์งœ ๋“ฑ์ด ํ•„์š”ํ–ˆ๋‹ค.

 

์ด๋ฒˆ ๋‹ฌ์˜ ์ฒซ ๋ฒˆ์งธ ์š”์ผ ๊ตฌํ•˜๊ธฐ

JavaScript์—์„œ๋Š” new Date()๋กœ Date ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. data ์˜ต์…˜์— year์™€ month๋ฅผ0์œผ๋กœ ์ดˆ๊ธฐํ™”ํ•ด์ค€ ๋’ค ์˜ต์…˜ ์ฒ˜๋ฆฌ ๋“ฑ์ด์ผ์–ด๋‚˜๋Š” created() ํ›… ๋‹จ๊ณ„์—์„œ ์•„๋ž˜ ์ฝ”๋“œ์ฒ˜๋Ÿผ init() ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ํ•œ๋‹ค. 

// Calendar.vue

data() {
	return {
    	year: 0,
        month: 0
   }
}

// ..
created() {
	this.init()
},
methods: {
	init(param) {
      if (param) {
          this.year = param[0];
          this.month = param[1];
          this.calendarDate();
        } else {
          const date = new Date();
          this.year = date.getFullYear();
          this.month = date.getMonth() + 1;

          this.calendarDate();
        }
    }
}

init()๋Š” param ์ด๋ผ๋Š” ์ธ์ž๋ฅผ ํ•˜๋‚˜ ๋ฐ›๋Š”๋ฐ, ์•ฑ์ด ๋งจ ์ฒ˜์Œ ์‹คํ–‰๋  ๋•Œ๋Š” param์ด ์กด์žฌํ•˜์ง€ ์•Š์œผ๋‹ˆ else๋กœ ๋“ค์–ด๊ฐ€ ์˜ค๋Š˜ ๋‚ ์งœ์˜ date ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ๊ทธ๋กœ๋ถ€ํ„ฐ year์™€ month๋ฅผ ํ•˜๋‚˜์”ฉ ์ถ”์ถœํ•œ๋‹ค. month์— 1์„ ๋”ํ•ด์ฃผ๋Š” ๊ฒƒ์€ getMonth()์˜ ๋ฐ˜ํ™˜๊ฐ’์ด ๋ฐฐ์—ด์ฒ˜๋Ÿผ 0-based index์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

init()์ด param์„ ๋ฐ›๋Š” ์ด์œ ๋Š” ๋‹ฌ๋ ฅ์—์„œ ๋‹ค๋ฅธ ๋‚ ์งœ๋กœ ์ด๋™ํ•˜๊ฑฐ๋‚˜, ๋‹ค๋ฅธ ํ•ด๋กœ ์ด๋™ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ดˆ๊ธฐํ™”ํ•ด์ฃผ์–ด์•ผ ํ•  ํ•„์š”๊ฐ€ ์žˆ์–ด์„œ๋‹ค.

 

getFirstDayLastDate(year, month) {
      const firstDay = new Date(year, month - 1, 1).getDay();
      const lastDate = new Date(year, month, 0).getDate();

      let lastMonth = month - 1;
      if (month === 1) {
        lastMonth = 12;
        year -= 1;
      }
      const prevLastDate = new Date(year, lastMonth, 0).getDate();
      return [firstDay, lastDate, prevLastDate];
},

 

์•„๊นŒ ๊ตฌํ•œ month์— + 1์„ ํ•ด์ค€ ์ƒํƒœ์ด๋‹ˆ, ์ด๋ฒˆ ๋‹ฌ์˜ ์š”์ผ์„ ๊ตฌํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” month ๊ฐ’์„ ๋‹ค์‹œ ์กฐ์ •ํ•ด์ค€๋‹ค. getDay() ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์š”์ผ์„ ๊ตฌํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ 0-based์ด๋ฏ€๋กœ 0์ด ์ถœ๋ ฅ๋œ๋‹ค๋ฉด ์ผ์š”์ผ์„ ์˜๋ฏธํ•œ๋‹ค.

๋งˆ์ง€๋ง‰ ๋‚ ์งœ ๊ตฌํ•˜๊ธฐ

// 2์›” 1์ผ์˜ ๋‚ ์งœ 
const date = new Date(2021, 1, 1);
// 2์›” 28์ผ์˜ ๋‚ ์งœ (๋‹ฌ์˜ ๋งˆ์ง€๋ง‰ ๋‚ ์งœ)
const lastDate = new Date(2021, 1, 0)
// 2์›” 27์ผ์˜ ๋‚ ์งœ (๋ง์ผ์—์„œ ํ•˜๋ฃจ ์ „)
const lastDateBefore = new Date(2021, 1, -1)

๋งˆ์ง€๋ง‰ ๋‚ ์งœ์˜ ๊ฒฝ์šฐ new Date(year, month, 0).getDate()๋กœ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด 2์›” 1์ผ์˜ ๋‚ ์งœ๋ฅผ ๊ตฌํ•˜๊ณ ์ž ํ•œ๋‹ค๋ฉด new Date(2021, 1, 1), ๋งˆ์ง€๋ง‰ ๋‚ ์งœ๋ฅผ ๊ตฌํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์„ธ ๋ฒˆ์งธ ์ธ์ž๋ฅผ 0์œผ๋กœ ๋น„์›Œ๋‘”๋‹ค. ๋งˆ์ง€๋ง‰ ๋‚ ์งœ์—์„œ ํ•˜๋ฃจ ์ „ ํ˜น์€ ์ดํ‹€ ์ „์„ ๊ตฌํ•œ๋‹ค ํ•˜๋ฉด ์Œ์ˆ˜๋ฅผ ์ด์šฉํ•ด -1, -2๋กœ ์‰ฝ๊ฒŒ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์ด์ „ ๋‚ ์งœ๋ฅผ ๊ตฌํ•  ๋•Œ๋Š” ํ˜„์žฌ ๋‹ฌ์ด 1์›”์ธ ๊ฒฝ์šฐ๋ฅผ ๊ณ ๋ คํ•œ๋‹ค. ์ฆ‰ month === 1์ผ ๋•Œ year์—์„œ 1๋ฅผ ๋นผ ์กฐ์ •ํ•˜๊ณ , lastMonth๋Š” ์ž๋™์œผ๋กœ 12๊ฐ€ ๋œ๋‹ค.

 

์ง์ „ ๋‹ฌ์˜ ๋งˆ์ง€๋ง‰ ๋‚ ์งœ๊นŒ์ง€ ๊ตฌํ•˜๊ณ , ๊ตฌํ•˜๊ณ ์ž ํ•œ ์„ธ ๊ฐ€์ง€ ๊ฐ’์„ ๋ฐฐ์—ด์— ๋‹ด์•„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

 

getFirstDayLastDate(year, month) {
      const firstDay = new Date(year, month - 1, 1).getDay();
      const lastDate = new Date(year, month, 0).getDate();

      let lastMonth = month - 1;
      if (month === 1) {
        lastMonth = 12;
        year -= 1;
      }
      const prevLastDate = new Date(year, lastMonth, 0).getDate();
      return [firstDay, lastDate, prevLastDate];
    },

์ด์ œ ๋‹ฌ์˜ ์ฒซ์งธ ๋‚ ๋ถ€ํ„ฐ ๋งˆ์ง€๋ง‰ ๋‚ ๊นŒ์ง€์˜ ๊ฐ’๋“ค์„ 2์ฐจ์› ๋ฐฐ์—ด์˜ ํ˜•ํƒœ๋กœ ๋‹ด๊ธฐ๋กœ ํ•œ๋‹ค. ๋‹ฌ๋ ฅ์€ table ํƒœ๊ทธ๋กœ ์งœ์„œ, ๊ฐ tr์— date ๋ฐฐ์—ด์„ v-for๋กœ ๋Œ๋ ค ์ถœ๋ ฅํ–ˆ๋‹ค.

 

date() {
  dates: [],
    year: 0,
    month: 0,
}

dates๋ผ๋Š” ๋นˆ ๋ฐฐ์—ด์„ ๋งŒ๋“ค์–ด์ค€๋‹ค. ์—ฌ๊ธฐ์— ๋ฐฐ์—ด์ธ ์›์†Œ๋“ค์ด ํ•˜๋‚˜์”ฉ ์ฑ„์›Œ์งˆ ๊ฒƒ์ด๋‹ค.

 

๋‹ฌ๋ ฅ์˜ ๋‚ ์งœ ๊ตฌํ•˜๊ธฐ (์ด์ „ ๋‚ ์งœ, ํ˜„์žฌ ๋‹ฌ์˜ ๋‚ ์งœ, ๋‹ค์Œ ๋‹ฌ์˜ ๋‚ ์งœ)

getDaysOfMonth(monthFirstDay, monthLastDate, prevMonthLastDate) {
      let day = 1;
      let prevDay = prevMonthLastDate - monthFirstDay + 1;
      let dates = [];
      let daysOfWeek = [];

      while (day <= monthLastDate) {
        if (day === 1) {
          this.getPrevDates(monthFirstDay, daysOfWeek, prevDay);
          this.padDates(daysOfWeek);
        }

        if (daysOfWeek.length === 7) {
          dates.push(daysOfWeek);
          day = daysOfWeek[daysOfWeek.length - 1];
          daysOfWeek = [];
        } else if (
          daysOfWeek.length < 7 &&
          daysOfWeek.indexOf(monthLastDate) > -1
        ) {
          this.padDates(daysOfWeek);
          dates.push(daysOfWeek);
          break;
        }
        day++;
        if (daysOfWeek.length <= 7) {
          daysOfWeek.push(day);
        }
      }
      return dates;
    },

 

getDaysOfMont() ๋ฉ”์„œ๋“œ์—์„œ๋Š” ํ•ด๋‹น ๋‹ฌ์˜ ๋‚ ์งœ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ด์ „ ๋‹ฌ์˜ ๋‚ ์งœ์™€ ํ…Œ์ด๋ธ”์˜ ๋งˆ์ง€๋ง‰ ์นธ์„ ๋งˆ์ง€๋ง‰ ๋‚ ์งœ๊ฐ€ ์ฑ„์šฐ์ง€ ๋ชปํ•˜๋ฉด ๋‹ค์Œ ๋‹ฌ์˜ ๋‚ ์งœ๋“ค์„ ๋ณผ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๊ทธ ๋‚ ์งœ๋“ค๋„ ๊ฐ™์ด ๊ฐ€์ง€๊ณ  ์˜ค๋„๋ก ํ•œ๋‹ค.

prevDay๋Š” ๋‹ฌ๋ ฅ์ด ์–ด๋–ค ์ˆซ์ž๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด์•ผ ํ•˜๋Š”์ง€ ๊ณ„์‚ฐํ•ด ๋„ฃ๋Š” ๋ณ€์ˆ˜์ด๋‹ค. ์ง์ „ ๋‹ฌ์˜ ๋งˆ์ง€๋ง‰ ๋‚ ์งœ(4์›”์˜ ๊ฒฝ์šฐ 3์›”์ด๋ฏ€๋กœ 31์ผ)์—์„œ ํ•ด๋‹น ์›”์˜ ์ฒซ ๋ฒˆ์งธ ๋‚ ์งœ์˜ ์š”์ผ (4์›”์˜ ๊ฒฝ์šฐ 1์ผ์ด ๋ชฉ์š”์ผ๋กœ 4)์„ ๋บ€ ํ›„ 1์„ ๋”ํ•ด์ค€๋‹ค.

 

31 - 4 + 1 = 28์ผ๋ถ€ํ„ฐ ๋‹ฌ๋ ฅ์ด ์‹œ์ž‘ํ•œ๋‹ค.

 

day๊ฐ€ ๋งˆ์ง€๋ง‰ ๋‚ ์งœ์ผ ๋•Œ๊นŒ์ง€ ๋ฐ˜๋ณตํ•˜๋Š” while ๋ฐ˜๋ณต๋ฌธ์—์„œ 1์ผ์ผ ๊ฒฝ์šฐ prevDay๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด ๋ง์ผ๊นŒ์ง€์˜ ๋‚ ์งœ๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” getPrevDates ์‚ฌ์šฉ์ž ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ณ , 7์ผ์ด ๋‹ค ์ฑ„์›Œ์ง€์ง€ ์•Š์•˜์œผ๋‹ˆ ์ด์–ด์„œ 1์ผ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด length 7์งœ๋ฆฌ daysOfWeek ๋ฐฐ์—ด์„ ์ฑ„์šฐ๋Š” padDates ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค. 

 

๋งŒ์ผ ๊ธธ์ด๊ฐ€ daysOfWeek์˜ ๊ธธ์ด๊ฐ€ 7์— ๋‹ค๋‹ค๋ฅด๋ฉด, dates ๊ฐ์ฒด๋กœ pushํ•ด์ฃผ๊ณ , ๋‹ค์‹œ daysOfWeek๋ฅผ ๋นˆ ๋ฐฐ์—ด๋กœ ์ดˆ๊ธฐํ™”ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค. ์ด๋•Œ day๋Š” push ํ•ด์ฃผ๊ธฐ ์ „ daysOfWeek์˜ ๋งˆ์ง€๋ง‰ ์š”์†Œ์™€ ๋™์ผํ•œ ๊ฐ’์ด๋ฏ€๋กœ day ๋ณ€์ˆ˜์— ๋„ฃ์–ด์ค€ ํ›„, ์กฐ๊ฑด๋ฌธ์ด ํ†ต๊ณผํ•˜๊ณ  ๋‚˜๋ฉด day++๋กœ ์•Œ๋งž์€ ์ˆซ์ž๊ฐ€ ์นด์šดํŠธ๋  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค. 1์”ฉ ์ฆ๊ฐ€ํ•˜๋Š” day๋Š” daysOfWeek๊ฐ€ ๊ฝ‰ ์ฑ„์›Œ์งˆ ๋•Œ๊นŒ์ง€ ๊ณ„์† ๋ฐ˜๋ณตํ•˜๊ณ  day = 1์ธ ์ผ€์ด์Šค์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ day๊ฐ€ ๋งˆ์ง€๋ง‰ ๋‚ ์งœ์— ๋‹ค๋‹ค๋ž์„ ๋•Œ date๋ฅผ padํ•ด์„œ daysOfWeek ๋ฐฐ์—ด์„ ์ฑ„์›Œ์ฃผ๋„๋ก ํ•œ๋‹ค.

 

getPrevDates(monthFirstDay, daysOfWeek, prevDay) {
      for (let j = 0; j < monthFirstDay; j++) {
        daysOfWeek.push(prevDay);
        this.prevDate.push(prevDay);
        prevDay += 1;
      }
    },
    padDates(daysOfWeek) {
      const len = daysOfWeek.length;
      const leftDays = 7 - len;
      if (len >= 0 && len < 7) {
        for (let i = 1; i <= leftDays; i++) {
          daysOfWeek.push(i);
          if (this.previewDate.length < leftDays) this.previewDate.push(i);
        }
      }
    },

 

์ด์ „ ๋‚ ์งœ๋ฅผ padํ•ด์ฃผ๋Š” ํ•จ์ˆ˜์™€ ๋‹ฌ์˜ ๋งจ ์•„๋ž˜ ์นธ์˜ ๋‚ ์งœ๋ฅผ padํ•ด์ฃผ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ๊ฐ ๋”ฐ๋กœ ๋งŒ๋“ค์—ˆ๋‹ค.

 

calendarDate() {
      const [
        monthFirstDay,
        monthLastDate,
        prevMonthLastDate
      ] = this.getFirstDayLastDate(this.year, this.month);
      this.dates = this.getDaysOfMonth(
        monthFirstDay,
        monthLastDate,
        prevMonthLastDate
      );
    },

์ด๋ ‡๊ฒŒ ๊ตฌํ•œ dates๋Š” ๋งจ ์ฒ˜์Œ ์ธ์Šคํ„ด์Šค ๋ฐ์ดํ„ฐ๋ฅผ ์ดˆ๊ธฐํ™”ํ•  ๋•Œ ๋นˆ ๋ฐฐ์—ด๋กœ ์„ ์–ธํ•ด๋‘์—ˆ๋˜ dates์— ๋‹ด๋Š”๋‹ค.

 

๋‹ฌ๋ ฅ ์ด๋™ํ•˜๊ธฐ

ํ™”์‚ดํ‘œ ๋ชจ์–‘ ์•„์ด์ฝ˜๊ณผ ์˜ค๋ฅธ์ชฝ์˜ side menu๋ฅผ ํ†ตํ•ด ๋‚ ์งœ๋ฅผ ์ด๋™ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ–ˆ๋‹ค. controlMonth() ๋ฉ”์„œ๋“œ๋กœ ๋‹ฌ์„, controlYear() ๋ฉ”์„œ๋“œ๋กœ ํ•ด๋ฅผ ์˜ฎ๊ธฐ๋„๋ก ํ–ˆ๋‹ค. ์ธ์ž๋ฅผ ๋‹ค๋ฅด๊ฒŒ ์ค˜์„œ ๋ฉ”์„œ๋“œ๋ฅผ ์žฌ์‚ฌ์šฉํ•œ๋‹ค.

 

controlMonth(p) {
      if (p === "prev") {
        this.currentMonth = this.month - 1;
        this.currentYear = this.year;
        if (this.month === 1) {
          this.currentMonth = 12;
          this.currentYear = this.year -= 1;
        }
      } else {
        this.currentMonth = this.month + 1;
        this.currentYear = this.year;
        if (this.month === 12) {
          this.currentMonth = 1;
          this.currentYear = this.year += 1;
        }
      }
      const param = [this.currentYear, this.currentMonth];
      this.init(param);
    },
    controlYear(p) {
      if (p === "prev") {
        this.currentYear = this.year - 1;
      } else {
        this.currentYear = this.year + 1;
      }
      const param = [this.currentYear, this.month];
      this.init(param);
    },

created() ํ›…์—์„œ ํ•œ ๋ฒˆ ์‚ฌ์šฉ๋˜์—ˆ๋˜ init์€ ์ด ๋ฉ”์„œ๋“œ๋“ค์—์„œ๋Š” param์„ ์ธ์ž๋กœ ๊ฐ–๊ณ  ์‹คํ–‰๋œ๋‹ค.

 

side menu๋ฅผ ํ†ตํ•ด ์ด๋™ํ•  ๋•Œ๋Š” ์˜ค๋Š˜ ๋‚ ์งœ๋กœ ๋˜๋Œ์•„๋„๋ก ํ•ด์ฃผ๋Š” ๋ฉ”์„œ๋“œ ํ•˜๋‚˜, ๊ฐ ๋‹ฌ์„ ํด๋ฆญํ–ˆ์„ ๋•Œ ํ•ด๋‹น ๋‹ฌ๋กœ ์ด๋™ํ•˜๋Š” ๋ฉ”์„œ๋“œ ํ•˜๋‚˜๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค. ๊ทธ๋Ÿฌ๊ณ ๋ณด๋‹ˆ ๋‹ฌ๋ ฅ์—์„œ ์‚ฌ์šฉ์ž๊ฐ€ ํ˜„์žฌ ๋ณด๊ณ  ์žˆ๋Š” ์—ฐ๋„๊ฐ€ ํ˜„์žฌ ์—ฐ๋„์™€ ๋‹ค๋ฅผ ๊ฒฝ์šฐ side menu๋ฅผ ์กฐ์ž‘ํ•˜๋ฉด ๋ฌด์กฐ๊ฑด ์˜ฌํ•ด ์•ˆ์˜ ๋‚ ์งœ๋“ค๋งŒ ๋ณผ ์ˆ˜ ์žˆ๋„๋ก ๋˜์–ด ์žˆ๋‹ค. ์‹œ๊ฐ„์ด ๋‚˜๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ์„ค์ •ํ•ด๋‘” ํ•ด ์•ˆ์—์„œ ๋‹ฌ์„ ์ด๋™ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋ฉด ์กฐ๊ธˆ ๋” ํŽธํ•  ๋“ฏ์‹ถ๋‹ค.

 

skipBy(p) {
      this.currentYear = new Date().getFullYear();
      if (p === "today") {
        this.currentMonth = new Date().getMonth() + 1;
      } else {
        this.currentMonth = p + 1;
      }
      const param = [this.currentYear, this.currentMonth];
      this.init(param);
    },

 

์—ฌ๊ธฐ๊นŒ์ง€๊ฐ€ ๊ธฐ๋ณธ ๊ธฐ๋Šฅ์„ ์œ„ํ•œ ๋ฉ”์„œ๋“œ๋“ค์ด๋ผ๋ฉด, CSS ์Šคํƒ€์ผ๋ง์„ ์œ„ํ•ด ์ถ”๊ฐ€ํ•œ ๋ฉ”์„œ๋“œ์™€ computed ์†์„ฑ์ด ๋ช‡ ๊ฐœ ์žˆ๋‹ค.

 

๋‹ฌ๋ ฅ ์Šคํƒ€์ผ๋ง์„ ์œ„ํ•œ ๋ฉ”์„œ๋“œ

์˜ค๋Š˜ ๋‚ ์งœ์— ์›์œผ๋กœ ๋งˆํฌ๋ฅผ ํ•˜๊ธฐ ์œ„ํ•ด์„œ getMatchedTodos()๋ผ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ๋งŒ๋“ค์–ด boolean ํƒ€์ž…์„ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ํ•˜๊ณ , v-for๋กœ ๋‚ ์งœ <td> ํƒœ๊ทธ๋ฅผ ๋ฐ˜๋ณตํ•˜๋ฉด์„œ ๊ทธ ์ค‘ ์˜ค๋Š˜ ๋‚ ์งœ์™€ ์ผ์น˜ํ•˜๋Š” ํƒœ๊ทธ์—๋งŒ :class ๋ฐ”์ธ๋”ฉ์„ ํ†ตํ•ด 'selected-date'๋ผ๋Š” ํด๋ž˜์Šค๋ฅผ ๋ถ™์—ฌ์ฃผ์—ˆ๋‹ค.

 

<tr v-for="(date, idx) in dates" :key="idx" class="flex w-full h-12 justify-around items-center mb-3">
  <td v-for="(day, index) in date" :key="index" class="w-12 h-12 flex flex-col justify-center items-center hover-date rounded-full"
:class="{'selected-date': day === currentDate && isCurrentDate, 'prev-dates': isPrevDates(day, idx)}">
            

 

prev-dates ํด๋ž˜์Šค๋Š” ์ด์ „ ๋‚ ์งœ๋“ค์ผ ๊ฒฝ์šฐ text color๋ฅผ ์˜…์€ ์ƒ‰์œผ๋กœ ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•ด ์ถ”๊ฐ€ํ–ˆ๋‹ค. ์‚ผํ•ญ ์—ฐ์‚ฐ์ž๋ฅผ ํ†ตํ•ด ์„ ํƒ์ ์œผ๋กœ class๋ฅผ ๋ฐ”์ธ๋”ฉํ•œ๋‹ค. ์—ฌ๋Ÿฌ ํด๋ž˜์Šค์— ๋Œ€ํ•œ ์กฐ์ž‘์ด ํ•„์š”ํ•  ๋•Œ๋Š” ๊ฐ์ฒด๋กœ ๋ฌถ๋Š”๋‹ค.

 

์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ํ•จ์ˆ˜๋“ค์„ ๋ฌถ์–ด์„œ ๋” ์ ์€ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์—ฐ์Šตํ•  ์ˆ˜ ์žˆ์—ˆ๋˜ ์˜ˆ์ œ์˜€๋‹ค. ๋ฌผ๋ก  ์•„์ง ์ฝ”๋“œ ๊ฐ€๋…์„ฑ์ด ๋‚ฎ๊ฒŒ ๊ธธ๊ฒŒ ์„œ์ˆ ๋˜์–ด ์žˆ์–ด์„œ ์ชผ๊ฐค ํ•„์š”๊ฐ€ ์žˆ๊ธด ํ•˜๋‹ค.

 

๋˜, Tailwinds๋ฅผ ์ œ๋Œ€๋กœ ์‚ฌ์šฉํ•ด๋ณธ ์ฒซ ๋ฒˆ์งธ ์˜ˆ์ œ์ด๊ธฐ๋„ ํ•œ๋ฐ, ๊ฐ„๋žตํ•œ prototyping์€ figma๋กœ ํ•˜๊ณ , ๊ทธ๋•Œ ๊ทธ๋•Œ ์ƒ๊ฐ๋‚˜๋Š” ๊ฑธ ๋ง๋ถ™์ด๋Š” ํ˜•ํƒœ๋กœ ๋งŒ๋“ค๋‹ค๋ณด๋‹ˆ ์Šคํƒ€์ผ๋ง์— ์‹œ๊ฐ„์„ ๋งŽ์ด ์“ฐ๋Š” ๊ฒŒ ์‹ซ์—ˆ๋Š”๋ฐ, ๊ทธ๋•Œ Tailwinds๋ฅผ ์‚ฌ์šฉํ•˜๋‹ˆ ์‹œ๊ฐ„์ด ๋ฌด์ฒ™ ์ ˆ์•ฝ๋๋‹ค. ์ž์ฃผ ์“ฐ๋Š” ์†์„ฑ๋“ค์€ ๊ฒน์น˜๋‹ค๋ณด๋‹ˆ ๋””์ž์ธ์— ํ†ต์ผ์„ฑ๋„ ๋ถ€์—ฌ๋˜์–ด์„œ ๋น ๋ฅด๊ฒŒ ๋น ๋ฅด๊ฒŒ ์ž‘์—…ํ•  ๋•Œ๋Š” ๋ฌด์ฒ™ ๋งŒ์กฑ์Šค๋Ÿฌ์› ๋‹ค.

 

๐Ÿ’Œ Calendar.vue ์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•œ ์ „์ฒด ์†Œ์Šค๋Š” ์ด๊ณณ์—์„œ