Как изменить data() свойство компонента VUE полученными с сервера данными?

Сайт на Laravel, пытаюсь написать корзину с использованием VUE. Изначально, данные c товарами в корзине передаются в шаблон, в data() свойство компонента, и страница корзины рендерится успешно.

6183a2881627f755662485.jpeg

Но необходимо из корзины изменять количество и удалять товары. Например, по клику для удаления товара из корзины отправляется AJAX запрос на сервер, обрабатывается – удаляется товар из корзины, и обработанные данные возвращаются обратно.

Но не могу сообразить, что делать с обновленными полученными с сервера данными? Как изменить свойство data() компонента VUE, что бы страница изменялась без перезагрузки?

Как я понимаю, при получении обработанных сервером данных, нужно изменить данные в data() – компонента, и страница изменится без перезагрузки. Запутался в документации VUE, прошу дать совет: куда смотреть? Прошу указать на соответствующий раздел документации, способ решения задачи или ссылку на гайд с примером.

На всякий случай в спойлере полный код компонента корзины:
spoiler

<div id="app">
        <cart-wrap-component :items="items"></cart-wrap-component>
    </div>
    <script>
        const app = Vue.createApp({
            data() {
                return {
                    items: {!! json_encode($data) !!}
                }
            }
        });
        const cartItemComponent = {
            props: ["item"],
            computed: {
                itemTotalPrice() {
                    return this.item.price*this.item.qty
                }
            },
            methods: {
                plus: function () {
                    this.item.qty++;
                    console.log(this.item.qty);
                },
                minus: function () {
                    if(this.item.qty>1){
                        this.item.qty--;
                        console.log(this.item.qty);
                    }
                },
                del: function(){
                    $.ajax(
                        {
                            method: "POST",
                            url: '/cart-delete',
                            data: {
                                _token: document.querySelector('meta[name=csrf-token]').content,
                                id: this.item.id
                            },
                            success: function (response) {
                               this.items = response.success;
                               console.log(response);
                            },
                            error: function (response) {
                                //console.log(response);
                                console.log('error');
                            }
                        });
                    //console.log(this.item.id);
                }
            },
            template: `<div class="cart_item">
										<div class="cart_img_wrap">
												<a :href="item.url" class="cart_img_link">
													<img :src="item.img" :alt="item.name" class="cart_img">
												</a>
										</div>

										<div class="cart_item_info">
											<a :href="item.url" class="cart_name_link">@{{item.name}}</a>
										</div>

										<div class="cart_item_buy_wrap">
											<div class="cart_item_sam_wrap">
												<div class="cart_item_sam"><span class="item-sam">@{{itemTotalPrice.toLocaleString()}}</span> руб.</div>
											</div>

											<div class="cart_item_counter_wrap">
												<div class="cart_counter">
													<span class="cart_counter__btn" v-on:click="minus">-</span>
													<input type="number" name="QUANTITY" :value="item.qty" size="5" class="cart_counter__value">
													<span class="cart_counter__btn" v-on:click="plus">+</span>
												</div>
											</div>

											<div class="cart_price_wrap">
												<span v-if="item.discound > 0" class="cart_item_price_o">@{{item.discound}} руб.</span>
												<div class="cart_price">@{{item.price.toLocaleString()}} руб.</div>
												<span class="cart_item_price_i">цена за 1 шт</span>
											</div>

										</div>
										<span class="cart_item_del" v-on:click="del"><span class="icon-close"></span></span>
									</div>`
        }

        app.component('cartWrapComponent', {
            props: ["items"],
            computed: {
                totalPrice() {
                    let overallРrice = 0;
                    let overallQty = 0;
                    let quantity =''
                    for (key in this.items){
                        overallРrice += this.items[key].price * this.items[key].qty;
                        overallQty += this.items[key].qty;
                    }

                    if (overallQty % 100 / 10 == 1) {
                        quantity = overallQty+' товаров';
                    } else {
                        switch (overallQty % 10) {
                            case 1:
                                quantity = overallQty +' товаров';
                                break;
                            case 2:
                                quantity = overallQty + ' товаров';
                                break;
                            case 3:
                                quantity = overallQty + ' товаров';
                                break;
                            case 4:
                                quantity = overallQty + ' товара';
                                break;
                            default:
                                quantity = overallQty + ' товаров';
                                break;
                        }
                    }
                    return { sum: overallРrice, qty: quantity}
                }
            },

            template: `<div class="cart_content">
										<div class="cart_info">
											<div class="cart_resault"><span class="cart_resault_text">Итого: </span><span>@{{totalPrice.sum.toLocaleString()}}</span> руб.</div>
												<button class="cart_btn" id="cartBtn">Оформить заказ</button>
										</div>
										<div class="cart_wrap">
											<div class="cart_header">
												<span class="cart_number">В корзине: <span>@{{totalPrice.qty}}</span></span>
											</div>
											<div class="cart_list">

												<cart-item v-for="item in items" :key="item.id" :item="item"></cart-item>

											</div>
										</div>
									</div>`,
            components: {
                'cart-item': cartItemComponent
            }
        });
        app.mount('#app');
    </script>

  • Вопрос задан
  • 217 просмотров
Пригласить эксперта
Ответы на вопрос 1
artloveyou
@artloveyou
Вам стоит для понимания упростить свой код, в общем случае это могло бы выглядеть
так:
<template>
  <div>
    {{ dataFromAPI }}

    тут вызов апи по событию, в вашем случае вы его к чему-нибудь привязываете
    <button @click="getAPI">Get API</button>
  </div>
</template>

<script>
// смешивать jQuery c Vue - плохой вариант, лучше используйте axios
import axios from 'axios'

export default {
  data() {
    return {
      // тут у вас реактивное свойство
      dataFromAPI: null,
    }
  },
  mounted() {
    // тут первый вызов апи при загрузке страницы
    this.getAPI()
  },
  methods: {
    getAPI() {
      return axios
          .get('https://api.your.address')
          .then(response => {
            if (response.data) {
              // когда апи возвращает данные передаем их реактивному свойству
              // и они обновляются без перезагрузки, как вам надо
              this.dataFromAPI = response.data
            }
          })
          // ловим ошибки
          .catch(error => {
            console.log(error);
          })
          .finally(() => {
            // если надо -- дополнительные действия (выключить лоадер, например)
          })
    }
  }
}
</script>


и разобравшись вернуться к тому что вы делаете.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы