[Vuejs]-How to style individual calendar items with v-bind: class

0👍

I managed to do it with 2 modifications:

first I added the v-bind:class to your HTML to add the class based on a method of the component

    <div v-for="(week, i) in getCalendar" class="d_day">
        <div v-for="day in week" class="day" v-bind:class="{ grey: isAnotherMonth(i, day) }">{{ day }}</div>
    </div>

then I created the method with the condition
if it’s the first week of the display and the daynumber is >15 it is the end of last month, the same goes for the last week (I chose 15 because it is half a month but anything between 8 and 20(for february) would do the job)

    isAnotherMonth(weekIndex, dayNumber) {
      return weekIndex === 0 && dayNumber > 15 || weekIndex === 4 && dayNumber < 15
    },

as asked in comments here a more readable version using if

    isAnotherMonth(weekIndex, dayNumber) {
      if(weekIndex === 0 && dayNumber > 15) {
        // first week and number > 15
        return true
      }
      if (weekIndex === 4 && dayNumber < 15) {
        // last week and number < 15
        return true
      }
      // day belong to current month
      return false
    },

and finally a snippets, it have problems with your css but it is still understandable

Vue.component("test-calendar", {
  template: `
  <div class="all">
    <div class="allсalendar">
      <div class="pagination">
        <div @click="prevPage"
              ><</div> 
        <p>{{ nameOfOneMonth }} {{ year }}</p>
        <div @click="nextPage"
              >></div> 
      </div>

      <div class="calendar">
        <div class="d_nameOfDays">
          <li v-for="day in nameOfDays" class="nameOfDays">{{ day }}</li>
        </div>

        <div v-for="(week, i) in getCalendar" class="d_day">
          <div v-for="day in week" class="day" v-bind:class="{ grey: isAnotherMonth(i, day) }">{{ day }}</div>
        </div>
      </div>
    </div>
  </div>`,
  data(){
    return{
      currentPage: 0,
      namesOfMonths: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
      nameOfOneMonth: '',
      nameOfDays: ['Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб', 'Вс'],
      date: new Date(),
      year: ''
    }
  },
  computed: {
    getCalendar(){
      return this.buildCalendar();
    }
  },
  mounted(){
    this.year = this.date.getFullYear();
    this.currentPage = this.date.getMonth();
    this.nameOfOneMonth = this.namesOfMonths[this.currentPage];
  },
  methods: {
    isAnotherMonth(weekIndex, dayNumber) {
      return weekIndex === 0 && dayNumber > 15 || weekIndex === 4 && dayNumber < 15
    },
    prevPage(){
      if (this.currentPage === 0) {
        this.currentPage = 12;
        this.year--;
      }
      this.currentPage--;
      this.nameOfOneMonth = this.namesOfMonths[this.currentPage];
    },
    nextPage(){
      if (this.currentPage === 11) {
        this.currentPage = -1;
        this.year++;
      }
      this.currentPage++;
      this.nameOfOneMonth = this.namesOfMonths[this.currentPage];
    },
    getYear(){
      this.year = this.date.getFullYear();
    },
    getLastDayOfMonth(month) { // нахождение числа последнего дня в месяце
      let dateDaysInMonth = new Date(this.year, month + 1, 0);
      return dateDaysInMonth.getDate();
    },
    getNumberOfFirstDayInMonth(month){ //нахождение номера первого дня в месяце
      let dateFirstDayInMonth = new Date(this.year, month, 1);
      return dateFirstDayInMonth.getDay();
    },
    buildCalendar(){
      let massOfMonth = [];
      for (let months = 0; months < 12; months++){
        massOfMonth.push(months);
        massOfMonth[months] = [];
        for ( let daysInMonth = 1; daysInMonth <= this.getLastDayOfMonth(months); daysInMonth++){
          massOfMonth[months].push(daysInMonth);
        }
        // Заполняем начало каждого месяца числами из прошлого месяца
        if(this.getNumberOfFirstDayInMonth(months) > 0){
          let t = this.getLastDayOfMonth(months-1) + 1;
          for(let b = 0; b <= this.getNumberOfFirstDayInMonth(months) - 2; b++){
            t--;
            massOfMonth[months].unshift(t)
          }
        }else if(this.getNumberOfFirstDayInMonth(months) === 0){
          let t = this.getLastDayOfMonth(months-1) + 1;
          for(let nulldays = 0; nulldays <= 5; nulldays++){
            t--;
            massOfMonth[months].unshift(t);
          }
        }
        //Заполняем конец каждого месяца числами из будущего месяца
        if(this.getNumberOfFirstDayInMonth(months + 1) > 1){
          let t = 0;
          for(let q = this.getNumberOfFirstDayInMonth(months + 1); q <= 7; q++){
            t++;
            massOfMonth[months].push(t);
          }
        } else if(this.getNumberOfFirstDayInMonth(months + 1) === 0){
          massOfMonth[months].push(1);
        }
      }

      // разбиение большого массива месяц на 
      // меньшие массивы которые имеют по 7 элементов
      var longArray = massOfMonth[this.currentPage];
      var size = 7;

      var newArray = new Array(Math.ceil(longArray.length / size)).fill("")
          .map(function() { 
            return this.splice(0, size) 
          }, longArray.slice());
       //--------------------------------------------------   
        return newArray; // вывод самого календаря
    }
  }
});

new Vue({el:"#vue"})
  body{
    background-color: #FAFAFA;
  }
  .allсalendar{
    background-color: white;
    margin-left: 30px;
    margin-right: 80%
  }
  .pagination{
    justify-content: space-between;
  }
  .pagination, .nameOfDays{
    display: flex;
  }
  .nameOfDays{
    font-size: 20px;
  }
  .pagination div{
    width: 30px;
    height: 30px;
    padding-top: 8px;
    margin-bottom: -5px;
    text-align: center;
    font-size: 20px;
    font-weight: bold;
    cursor: pointer;
  }
  .pagination div:active{
    color: #9D9D9D;
  }
  .pagination div:hover{
    color: white;
    background-color: #DEDEDE;
  }
  .pagination p{
    margin: 10px auto 5px auto;
    text-align: center;
    font-weight: bold;
    font-size: 18px;
  }
  .d_nameOfDays{
    margin: 5px auto 5px auto;
    padding-left: 10px;
    background-color: #DEDEDE;

  }
  .nameOfDays, .day{
    list-style-type: none;
    text-align: center;
    cursor: pointer;
  }
  .d_day, .d_nameOfDays{
    display: grid;
    grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
  }
  .day{
    font-size: 18px;
  }
  .day:hover {
    background: #16B9DE;
    color: white;
    border-radius: 10%;

  }
  .grey{
    color: red;
  }
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="vue">
<test-calendar></test-calendar>
</div>

Leave a comment