@KORICA67

Как правильно отследить изменения массива Vue Js переданного через props?

Добрый день , имеется проблема ,сделал вот такой элемент vue представляющий из себя карточку товара/карточку товара с выбором доп опций ,все рендерится нормально ,меняются значения товара при клике ,в корзину забрасываются но вот к сожалению с измененными значениями товар попадающий в корзину после добавленного обычного товара без вариаций размера или начинки не считаются между собой сразу а только после захода в корзину и обратного выхода из нее допустим в раздел категорий

<template>

    <div class="ar-catalog-item">
        <span class="ar-catalog-item__badge">
            <img :src="('../assets/images/' + product_data.badge)" alt="">
            {{ product_data.badge }}
        </span>

        <img class="ar-catalog-item__img"
         :src="require('../assets/images/' + product_data.image)" alt="img">
        <!-- <div v-for="(index, weight) in selectedVariation"
         :key="weight"> Вес {{ index.weight }}</div> -->

        <p class="ar-catalog-item__sku">{{ product_data.sku }}</p>
        <i class="ar-catalog-item__bju">i</i>
        <p class="ar-catalog-item__name">{{ product_data.name }} {{product_data.topping}}</p>
        <p class="ar-catalog-item__except">{{ product_data.except }}</p>

        <p v-if="product_data.type == 'pizza'" 
        class="ar-catalog-item_sku_variations">Выберите размер</p>

        <div v-if="product_data.type == 'pizza'">
            <div class="variations" 
            v-for="(variation,i) in product_data.variations" 
            :key="variation.variation_index">
                <a class="ar-variable"
                 :class="{ active: nowActive == i }"
                  @click="selectSize(variation,i)">
                    {{ variation.size }}
                </a>
            </div>
        </div>


        <p v-if="product_data.type == 'wok'"
         class="ar-catalog-item_sku_variations">Выберите начинку</p>

        <div v-if="product_data.type == 'wok'">
            <div class="variations"
             v-for="(variation,i) in product_data.variations"
              :key="variation.topping">
                <a class="ar-variable"
                 :class="{ active: nowActive == i }" 
                 @handler="selectSize(variation,i)">
                    {{ variation.topping }}
                </a>
            </div>
        </div>



        <div class="ar-catalog-item-bottom">
            <p class="ar-catalog-item-bottom__price"> Цена: {{ product_data.price }}₽</p>


            <button @click="addToCart" class="ar-catalog-item-bottom__add_to_cart_btn btn">хочу</button>
            <!-- <div class="ar-catalog-item-qty">
                <span 
                v-if="product_data.quantity > 1"
                 class="ar-catalog-item-qty_btns">
                    <button class="item_quantity_btn"
                     @click="decrementInProductCard">-</button>
                    {{ product_data.quantity }}
                    <button class="item_quantity_btn" 
                    @click="addToCart">+</button>
                </span>
            </div> -->
        </div>
    </div>

</template>

<script>



import { mapActions } from 'vuex';


//* Миксин позволяющий смешивать массивы *//

const myMixin = {

};


export default {

    mixins: [myMixin],
    name: 'ar-catalog-item',
    components: { },

    props: {
        product_data: {
            type: Object,
            default() {
                return {}
            }
        },

    },

    data() {

        return {

            nowActive: '',
           
     
            

        }
    },

    created() { },

    watch: {

        
            
          
   

},
    computed: {

     

},


//* Метод отвечающий за выбор размера и реактивную смену значений веса и цены зависимо от размера товара либо топпинга *//

    methods: {


        selectSize(i, nowActive) {



            const self = this;
            self.nowActive = nowActive;

            i = i || 0
            let vm = this;
            
            vm.product_data.price = i.price
            vm.product_data.size = i.size
            vm.product_data.sku = i.weight
            vm.product_data.topping = i.topping
            vm.$set(vm.selectedVariation,i || !vm.selectedVariation,i );
            vm.$emit('select-size',i);
           
        },




        ...mapActions([

        ]),
        //* Кнопки отвечающие за действие увелечения и убавления количества в корзине из карточки товара *//

        addToCart() {
            this.$emit('addToCart', this.product_data  ); //* Добавляем в корзину товар

        },

        decrementInProductCard() {  //* Убавляем товар
            let pd = this;
            pd.$emit(
                'decrementInProductCard',
                pd.product_data.quantity--)

        }

    },
    mounted() {
        this.$set(this.product_data , 'quantity', 1)


    }
}


</script>

<style lang="scss">
.ar-catalog-item {
    padding: 15px;
    position: relative;
    flex-direction: column;
    border-color: transparent #00000028 #f2f2f226 transparent;
    border-style: solid;
    border-width: 1px;
    overflow: hidden;

    &__img {
        width: 100%;
        transition: 1s;

    }

    &__img:hover {
        transform: scale(1.2);
    }

    &__name {

        color: rgb(255, 255, 255);
    }

    &__except {
        font-size: 12px;
        font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        color: rgb(255, 255, 255);
        text-align: left;
    }

    &__sku {
        font-size: 14px;
        text-align: left;
        color: rgb(255, 255, 255);
        border-radius: 50%;
    }

    &__bju {
        max-height: 8px;
        max-width: 10px;
        font-style: normal;
        border: 1px solid whitesmoke;
        border-radius: 50%;
        padding-top: 1px;
        padding-left: 5px;
        padding-right: 5px;
        padding-bottom: 1px;

    }


    &__badge {
        position: absolute;
        top: 0;
        right: 5;
        font-size: 14px;
        color: whitesmoke;
        background: rgb(131, 58, 180);
        background: linear-gradient(90deg, rgba(131, 58, 180, 1) 0%,
                rgba(253, 29, 29, 1) 54%, rgba(252, 176, 69, 1) 100%);
        border-radius: 25px;
        overflow: hidden;
    }

    &_sku_variations {
        font-size: 12px;
    }
}

.ar-catalog-item-bottom {
    position: bottom;
    padding-top: 10px;
    color: rgb(255, 255, 255);
    flex-grow: 1;
    height: 35px;
    flex-direction: row;
    justify-content: space-between;
    display: inline-flex;
    align-items: center;

    &__price {

        color: rgb(255, 255, 255);
    }

    &__add_to_cart_btn {

        cursor: pointer;
        margin-left: 20px;
        font-size: 18px;
        align-items: inherit;
        width: 80px;
        height: 25px;
        transition: background-color .3s ease;
        background-color: #ff6900;
        border: 0px;
        border-radius: 30px;
        color: whitesmoke;
    }

    &__add_to_cart_btn:active {
        background-color: #eeee;

    }

    .item_quantity_btn {
        color: #fff;
        background-color: #ff6900;
        border-radius: 50%;
        height: 30px;
        width: 30px;
        border-style: none;
        display: flex;
        justify-content: center;
        align-items: center;
        font-size: 18px;
        cursor: pointer;
        -webkit-transition: all .2s ease-out;
        transition: all .2s ease-out;

    }

    .ar-catalog-item-qty {
        position: absolute;
        bottom: 15px;
        right: 20px;
        justify-content: center;
        align-items: center;


    }

    .ar-catalog-item-qty_btns {
        font-size: 16px;
        padding-left: 5px;
        padding-right: 5px;
        display: flex;
        max-height: 25px;
        width: 80px;
        border-radius: 25px;
        justify-content: space-between;
        position: bottom;
        flex-grow: 1;
        height: 35px;
        flex-direction: row;
    }


    .ar-catalog-item:hover {

        border: 11px solid $color;

    }


}

.ar-variations-btn {
    cursor: pointer;
    color: whitesmoke;
    background-color: black;
    border: 1px solid $color;
    backdrop-filter: blur;
}

.ar-variable:hover {
    cursor: pointer;
    background: rgb(68, 68, 68);
}

.ar-variable.active {
    cursor: pointer;
    background: red;
    border-color:red;
}

.variations {
    display: inline-flex;
    flex-flow: row;
    overflow-y: hidden;
    white-space: nowrap;

}


.ar-variable {
    display: inline;
    text-align: center;
    font-size: 14px;
    cursor: pointer;
    margin: $margin;
    padding-top: 5px;
    padding-bottom: 5px;
    padding-left: 7px;
    padding-right: 7px;
    border: 1px solid;
    background-color: transparent;
    border-color: $color;
    border-radius: 50px;
    justify-content: center;
    align-items: center;

}
</style>
  • Вопрос задан
  • 146 просмотров
Пригласить эксперта
Ваш ответ на вопрос

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

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