Optimize rendering of inputs

Viewed 27

I have this code :

<div v-if="room.expanded">
  <div class="panel position-relative panel-content dates-panel">
    <div class="dates-header d-flex">
      <div class="dates-scroller" :key="`datesHeader`+room.id">
      </div>
      <div class="dates-container">
        <overlay-scrollbars
          :ref="`datesHeader`+room.id"
          :options="datesScrollOptions"
          :data-id="room.id"
        >
          <div class="dates d-flex">
            <div class="month" v-for="(month, i) in dates" :key="month.month+i">
              <span> {{ month.month }} </span>
              <div class="days d-flex">
                <div
                  class="day"
                  v-for="(day, index) in month.days"
                  :key="index+day.d+room.id"
                  :class="{'we': day.w>4, 'wee': day.w>5}"
                >
                  <span class="t">{{ day.t }}</span>
                  <span class="wd">{{ day.d }}</span>
                </div>
              </div>
            </div>
          </div>
        </overlay-scrollbars>
      </div>
    </div>
  </div>

  <div class="room-data d-flex">
    <div class="headers">
      <div class="header">{{ $t('calendar.roomStatus') }}</div>
      <div class="header">{{ $t('calendar.roomAvail') }}</div>
      <div class="header">{{ $t('calendar.roomPrice') }}
        <span v-if="room.occupancy.std <= 3">
          <icon width="11" height="11"  v-for="i in room.occupancy.std" :key="i+room.id" type="user"/>
        </span>
        <span v-else>
          <icon width="11" height="11"  :key="'icon'+i+room.id" type="user"/> &times; {{ room.occupancy.std }}
        </span>
        <span class="asset" v-html="currencySymbol()"></span>
      </div>
      <div
        class="header restriction"
        :class="{ 'd-none': !isRestrictionShown(rts.id), 'last-shown': lastShownRestriction(rts.id) }"
        v-for="(rts, i) in restrictionOptions"
        :key="rts.id + i">
        <span>{{ rts.text }}</span>
        <icon width="16" height="16" v-b-tooltip:page-calendar.right="rts.tip" type="info"/>
      </div>
    </div>
    <div class="rows" ref="roomRows">
      <div class="data room-status">
        <div class="day" v-for="(day,i) in data[room.id]"
             :key="day.i+i+room.id" :class="day.avail>0 && !day.csale ? 'bookable' : 'blocked'"></div>
      </div>
      <div class="data room-editable" data-field="avail">
        <div
          class="day"
          v-for="(day,i) in data[room.id]"
          @click.self="focusField($event)"
          :key="day.i+i+room.id"
          :class="day.avail>0 && !day.csale ? 'bookable' : 'blocked'"
        >
          <spinner v-if="isDayUpdating(room.id, day.i, 'avail')"/>
          <div v-else-if="isDayUpdated(room.id, day.i, 'avail')" class="day-updated">
            <icon width="18" height="18" type="ok-tick"/>
          </div>
          <b-input
            :value="day.avail" v-else
            @focus.prevent="selectField($event, day)"
            @mouseup.stop.prevent
            @blur="deselectField"
            @keyup.esc="resetField"
            @change.capture="updateField($event, room.id)"
          />
        </div>
      </div>
      <div class="data room-editable" data-field="price" :class="{ 'last-shown': !selectedRestrictions.length}">
        <div
          class="day"
          v-for="(day,i) in data[room.id]"
          @click.self="focusField($event)"
          :key="day.i+i"
          :class="day.avail>0 && !day.csale ? 'bookable' : 'blocked'"
        >
          <spinner v-if="isDayUpdating(room.id, day.i, 'price')"/>
          <div v-else-if="isDayUpdated(room.id, day.i, 'price')" class="day-updated">
            <icon width="18" height="18" type="ok-tick"/>
          </div>
          <b-input
            :value="day.price" v-else
            :disabled="day.avail==0"
            @focus.prevent="selectField($event, day)"
            @mouseup.stop.prevent
            @blur="deselectField"
            @keyup.esc="resetField"
            @change.capture="updateField($event, room.id)"
          />
        </div>
      </div>

      <div
        v-for="rts in restrictionOptions"
        :key="rts.id"
        class="data room-editable"
        :class="{ 'd-none': !isRestrictionShown(rts.id), 'last-shown': lastShownRestriction(rts.id) }"
        :data-field="rts.fld"
      >
        <div
          class="day"
          v-for="(day,i) in data[room.id]"
          @click.self="focusField($event)"
          :key="day.i+i+'day'"
          :class="day.avail>0 && !day.csale ? 'bookable' : 'blocked'"
        >
          <spinner v-if="isDayUpdating(room.id, day.i, rts.fld)"/>
          <div v-else-if="isDayUpdated(room.id, day.i, rts.fld)" class="day-updated">
            <icon width="18" height="18" type="ok-tick"/>
          </div>
          <template v-else>
            <b-input
              class="booking_slot"
              v-if="!rts.cb"
              :value="day[rts.fld]"
              :disabled="day.avail==0"
              @focus.prevent="selectField($event, day)"
              @mouseup.stop.prevent
              @blur="deselectField"
              @keyup.esc="resetField"
              @change.capture="updateField($event, room.id)"
            />
            <check-box
              v-else
              empty
              :value="day[rts.fld]"
              :disabled="day.avail==0"
              @input="updateField($event, room.id, day, rts.fld)"
            />
          </template>
        </div>
      </div>
    </div>
  </div>
</div>

So this code is building a kind of calendar for buildings with multiple rooms, for a period; Let's say for 30 days, if we have 5 element for one room = 30 (days) * 5 (elements) = 150 inputs for one room, and if I have 20 rooms = 20(rooms) * 150 = 3000 inputs; the rendering is very slow and I don't know if is possible to reduce this time, can you give me please some advices ?

0 Answers
Related