M
M
Maxim Volkov2021-11-04 12:11:16
Vue.js
Maxim Volkov, 2021-11-04 12:11:16

How to change the data() property of a VUE component with data received from the server?

Laravel site, trying to write a shopping cart using VUE. Initially, the data with the items in the cart is passed to the template, in the component's data() property, and the cart page renders successfully.

6183a2881627f755662485.jpeg

But it is necessary to change the quantity and remove goods from the basket. For example, on a click to remove an item from the cart, an AJAX request is sent to the server, processed - the item is removed from the cart, and the processed data is returned back.

But I can't figure out what to do with the updated data received from the server? How to change the data() property of the VUE component so that the page changes without reloading?

As I understand it, when receiving data processed by the server, you need to change the data in the data () component, and the page will change without reloading. Confused in the VUE documentation, please give advice: where to look? Please indicate the relevant section of the documentation, a way to solve the problem or a link to a guide with an example.

Just in case, in the spoiler, the full code of the basket component:

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>

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
artloveyou, 2021-11-04
@artloveyou

You should simplify your code for understanding, in the general case it could look like
this:

<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>

and having figured out to return to what you are doing.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question