VueJs // V-for с v-модалом // Ошибка обновления данных после нажатия кнопки - PullRequest
1 голос
/ 07 мая 2019

ОБНОВЛЕНО !!! Добавлен полный код компонента: Я сделал входные данные через цикл v-for. Список входных данных зависит от ответа API. Мне нужны кнопки «плюс» и «минус», чтобы изменить значение ввода. Я почти нахожу решение, но значение изменяется только при смене входных данных, но не при нажатии кнопки. Вот мой код ...

 <template>
  <div class="allPlaces" id="allPlaces">
    <div class="wiget__row wiget__row--top" id="topRow">
      <div class="wiget__details wiget__details--allPlaces">
        <div class="wiget__logo">
          <img class="wiget__img wiget__img--logo" width="28" height="30" src="../../img/kassy_logo_img.png" alt="">
          <img class="wiget__img wiget__img--logoTXT" width="59" height="28" src="../../img/kassy_logo_text.png" alt="">
        </div>
        <div class="wiget__eventDetails">
          <p class="wiget__eventName">{{this.show[0].title}}</p>
          <div class="wiget__place">
            <span class="wiget__venue">{{this.building[0].title}}, </span>
            <span class="wiget__venueHall">{{this.hall[0].title}}</span>
          </div>
          <div class="wiget__dateOfEvent">
            <span class="wiget__time">{{this.getTime(this.event[0].date)}}</span>
            <span class="wiget__date">{{this.getDate(this.event[0].date)}}</span>
          </div>
        </div>
      </div>
    </div>

    <div class="allPlaces__wrapper">
      <h1 class="allPlaces__title">Оформление заказа</h1>
      <p class="allPlaces__description">Для оформления заказа выберите нужное количество мест</p>
      <div class="allPlaces__content">
        <div class="allPlaces__entrance" v-for="(entrance, index) in places.entrance" :key="entrance.id">
          <div class="allPlaces__infoBlock">
            <div>
              <div class="allPlaces__available">
                <span class="allPlaces__label allPlaces__label--places">Доступно мест:</span>
                <span class="allPlaces__data">&nbsp{{entrance.vacant_places}}</span>
              </div>
              <div class="allPlaces__title allPlaces__title--entrance">{{getEntranceName(entrance)}}</div>
            </div>
            <div class="allPlaces__price">
              <span class="allPlaces__label">Цена: </span>
              <span class="allPlaces__data">{{entrance.price}}</span>
            </div>
          </div>

          <div class="allPlaces__orderBlock">
            <div class="allPlaces__inputBlock">
              <input class="allPlaces__input" type="number" name="amount" v-bind:id="tickets"
                    v-model="tickets[index]" @blur="showLabel($event, index)">
              <label class="allPlaces__label allPlaces__label--input"
                     @click="hideLabel($event, index)">Количество мест

              </label>
            </div>

            <div class="allPlaces__btnBlock">
              <button class="allPlaces__btn allPlaces__btn--minus" type="button" name="button"
                      @click="removeTicket(index)"></button>
              <button class="allPlaces__btn allPlaces__btn--plus" type="button" name="button"
                      @click="addTicket(index)">
              </button>
            </div>
            <button class="allPlaces__btn allPlaces__btn--confirm" type="button" name="button"
                  @click="addEntrancePlaceToCart(entrance, index)">
                  <img class="allPlaces__img allPlaces__img--cart" src="../../img/cartWhite.png" alt="Корзина">
                  <span class="allPlaces__text allPlaces__text--cart">В корзину</span>
            </button>
          </div>
        </div>
      </div>
    </div>

    <div class="wiget__row wiget__row--bottom" id="bottomRow">
       <div class="wiget__row">
         <div class="wiget__amountBlock">
           <span class="wiget__tickets">
             <span>Билеты:</span>
             <span class="wiget__amount wiget__amount--tickets">{{this.ticketsInCart.count}}</span>
             <span>шт.</span>
           </span>
           <div class="wiget__money">
             <span class="wiget__money wiget__money--label">Итого:</span>
             <p>
               <span class="wiget__amount wiget__amount--money">{{this.ticketsInCart.total}}&nbsp</span>
               <span class="wiget__amount wiget__amount--money">руб.</span>
             </p>
           </div>
         </div>
         <div class="wiget__btnBlock">
           <button class="wiget__btn wiget__btn--goToHall" type="button" name="button"
                   @click="goToHall()">
                 Выбрать на схеме
           </button>
           <button class="wiget__btn wiget__btn--confirm" type="button" name="button"
           @click="goToCartPage($event)">Оформить заказ</button>
         </div>
       </div>
       <div class="wiget__row wiget__row--service">
         <span class="wiget__service">Сервис предоставлен:</span>
         <a href="https://www.kassy.ru" class="wiget__company">Kassy.ru</a>
       </div>
     </div>
  </div>
</template>

<script>
import vueMethods from '../../mixins/methods'
import { mapState } from 'vuex'

export default {
  name: 'allPlaces',
  mixins: [vueMethods],
  data () {
    return {
      tickets: []
    }
  },
  mounted () {
    this.$nextTick(function () {
      window.addEventListener('resize', this.updateAllPlacesOnResize)
      this.setupAllPlaces()
    })
  },
  methods: {
    setupAllPlaces () {
      let allPlaces = document.getElementById('allPlaces')
      let topRow = document.querySelector('.wiget__row--top')
      let wrapper = document.querySelector('.allPlaces__wrapper')
      let bottomRow = document.querySelector('.wiget__row--bottom')

      let allPlacesHeight = allPlaces.clientHeight
      let topRowHeight = topRow.clientHeight
      let bottomRowHeight = bottomRow.clientHeight

      let wrapperHeight = allPlacesHeight - topRowHeight - bottomRowHeight
      console.log('topRowHeight ', topRowHeight)
      console.log('allPlacesHeight ', allPlacesHeight)
      console.log('bottomRowHeight ', bottomRowHeight)
      console.log('wrapperHeight ', wrapperHeight)
      wrapper.style.minHeight = wrapperHeight + 'px'
    },
    updateAllPlacesOnResize (event) {
      this.setupAllPlaces()
    },
    getEntranceName (entrance) {
      let sectionId = entrance.section_id
      let section = this.section
      let sectionName = section.filter(function (e) {
        return e.id === sectionId
      })

      return sectionName[0].title
    },
    addTicket (index) {
      console.log(this.tickets)
      console.log(this.tickets[index])
      this.tickets[index] = parseInt(this.tickets[index]) + 1
      return this.tickets
    },
    removeTicket (index) {
      this.tickets[index] = parseInt(this.tickets[index]) - 1
    },
    addEntrancePlaceToCart (entrance, index) {
      console.log('entrance.id to add to cart ', entrance.id)
      let db = this.db
      let places = parseInt(this.tickets[index])
      console.log('places ', places)
      console.log('index ', index)
      let sessionId = this.sessionId
      let entranceId = parseInt(entrance.id)
      let params = {db, places, sessionId, entranceId}
      this.$store.dispatch('addEntrancePlaceToCart', params) // Добавили место в корзину
    },
    goToHall () {
      this.$store.dispatch('closeAllPlaces')
      this.$store.dispatch('openHallPlan')
    },
    hideLabel (e, index) {
      console.log('CLICKED')
      console.log('index click', index)
      let input = document.getElementsByClassName('allPlaces__input')
      let target = e.target
      input[index].focus()
      console.log('this.tickets ', this.tickets)
      console.log(target)
      if (this.tickets === '') {
        target.style.display = 'block'
      } else {
        target.style.display = 'none'
      }
    },
    showLabel (e, index) {
      console.log('BLUR')
      console.log('index blur', index)
      let label = document.getElementsByClassName('allPlaces__label allPlaces__label--input')
      console.log(this.tickets[index])
      if (this.tickets[index] === '' || this.tickets[index] === undefined) {
        label[index].style.display = 'block'
      } else {
        label[index].style.display = 'none'
      }
    }
  },
  destroyed () {
    window.removeEventListener('resize', this.setupAllPlaces)
  },
  computed: {
    ...mapState({
      db: state => state.onload.currentDb,
      currentEvent: state => state.onload.currentEvent,
      modals: state => state.modals,
      metric: state => state.onload.eventData.metric,
      section: state => state.onload.eventData.section,
      show: state => state.onload.eventData.show,
      event: state => state.onload.eventData.event,
      building: state => state.onload.eventData.building,
      hall: state => state.onload.eventData.hall,
      places: state => state.onload.eventData.places,
      placesSeated: state => state.onload.eventData.places.place,
      sessionId: state => state.cart.sessionId,
      ticketsInCart: state => state.cart.ticketsInCart
    })
  }
}
</script>

<style scoped lang="stylus">
@import '../../styles/Root/allPlaces'
@import '../../styles/Root/wiget'
</style>

Пожалуйста, сообщите

enter image description here

1 Ответ

1 голос
/ 08 мая 2019

Вы tickets не правильно инициализированы. Данные заполнили пустой массив, но шаблон добавит новый элемент без использования способа добавления реактивности VueJ.

То, что происходит, похоже на:

let tickets = [];
tickets[0] = ...;

В VueJs вы должны использовать push, чтобы вставить элемент в массив и не использовать «разреженную реализацию».

Таким образом, когда ваш places заполняется в вашем магазине, вы должны создать таблицу заявок по размеру. Что-то похожее на следующее в наблюдателе или в другом месте в зависимости от ваших потребностей:

this.tickets = this.place.map(_ => 0);
...