Vue.js Axios 错误 HTTP 请求更改我的数组但不显示更改

Vue.js Axios bug HTTP request change my array but don't show change

我在vue中有一个很奇怪的问题。js/axios。

场景 1:清除我的产品变量 BEFORE 发送 HTTP 请求(参见“<<<<< SCENARIO 1”标记) .然后使用新数组设置产品变量。 它有效,但我们看到闪烁(由于 HTTP 请求持续时间)。 所以我决定清除产品变量 IN 请求。

场景 2:清除我的产品变量 IN HTTP 请求。 (参见“<<<<< 场景 2”标记)。

但我不知道为什么在场景 2 中:我的产品变量被修改但视图没有改变!所以我的产品变量有 3 个相关数量的产品。然后一种产品的数量发生变化,因此我清除了产品变量并使用 HTTP 请求进行刷新。一切都一样,但 1 种产品的数量发生了变化。但视图并未反映这一点!

let Cart = {

    components: { Product },

    data: function() {
        return {
            products: []
        }
    },

    template: "<div><h3>Cart:</h3>" +
        '<product @productChanged="updateProductsCart(product)"' +
        'style="display: inline-block; max-width: 90px;" v-for="product in products"' +
        ':id="product.id" :name="product.name" :priceWithCurrency="product.priceWithCurrency"' +
        ':initQuantity="product.initQuantity" :picture="product.picture" :hasDeletedBtn="true"' +
        ':isProductRefreshAuto="false"></product>' +
    "</div>",

    methods: {

        getAllProducts: function () {

            let $this = this;
            $this.clearProductsList();<<<<< SCENARIO 1

            tdtdapi.get( '/cart/products/me', configs

            ).then(function (response) {

                $this.clearProductsList();<<<<< SCENARIO 2

                console.log("getAllProducts.then >")
                console.log(response)
                let products = [];

                for( let i = 0, l = response.data.length; i < l; i++ ){
                    let product      = response.data[i],
                        productToAdd = {
                            "name": "Product ",//todo delete raw value
                            "priceWithCurrency": 45
                        };
                    //todo: create a class Product
                    for( let prop in product ){
                        if( prop === "product" )     productToAdd.id = product[prop];
                        if( prop === "name" )        productToAdd.name = product[prop];
                        if( prop === "quantity" )    productToAdd.initQuantity = product[prop];
                        // if( prop === "description" ) productToAdd.description = product[prop];
                        if( prop === "price" )       productToAdd.priceWithCurrency = product[prop];
                        if( prop === "picture" )     productToAdd.picture = product[prop];
                    }
                    products.push(productToAdd);
                }

                $this.setProducts(products);

            }).catch(function (error) {
                console.log(error);
            });
        },

        updateProductsCart: function( product ) {
            console.log("updateProductsCart >")
            console.log(product)
            this.getAllProducts();
        },

        setProducts: function(products) {
            console.log("setProducts >")
            console.log(products)
            this.products = products;
            console.log(this.products)
        },

        clearProductsList: function() {
            this.products.splice( 0, this.products.length );
        }
    },

    mounted() {
        this.getAllProducts();
    },

    computed: {

    }
};


var app = new Vue({
    el: "#app",

    components: {
        "ProductsList": ProductsList,
        "Cart": Cart
    }
});

有产品组件,如果有帮助的话:

let Product = {

    data() {
        return {
            quantity: this.initQuantity,
            price: this.getPriceWithoutSymbols()
        }
    },

    props: {
        id: { type: Number, required: true },
        name: { type: String, required: true },
        description: { type: String, default: "" },
        priceWithCurrency: { type: Number, required: true },
        initQuantity: { type: Number, default: 0 },
        picture: { type: String, default: "" },
        hasDeletedBtn: { type: Boolean, default: false },
        isProductRefreshAuto: { type: Boolean, default: true }
    },

    template: '<article :id="id">'  +
    '<div>{{ name }}</div>' +
    '<div>{{ description }}</div>' +
    '<div>{{ price }}</div>' +
    '<div><img :src="picture"/></div>' +
    '<div>Quantity: {{ quantity }}</div>' +
    '<div>Total for this product: {{ totalPrice }}</div>' +
    '<div>' +
    '<button @click="decrementQuantity" type="button">-</button>' +
    '<button @click="incrementQuantity" type="button">+</button>' +
    '<br /><button v-if="hasDeletedBtn" @click="deleteProductQuantity" type="button">Delete product</button>' +
    '</div>' +
    '</article>',

    methods: {

        addQuantity( valueToAdd ){

            //if quantity 0 to 1 ==> post
            if( (this.quantity === 0) && (valueToAdd >= 1) ){
                this.postProductQuantity(valueToAdd);
            }

            //if quantity 1 to 0 ==> delete
            else if( (this.quantity === 1) && (valueToAdd === -1) ){
                this.deleteProductQuantity();
            }

            //else ==> put
            else{
                this.putProductQuantity(valueToAdd);
            }
        },

        postProductQuantity(valueToAdd){
            console.log("POST")
            let $this = this;
            tdtdapi.post( '/cart/products/me', querystring.stringify({
                    product: $this.id,
                    quantity: valueToAdd
                }), configs
            ).then(function (response) {
                console.log(response);
                $this.setQuantity(response.data.quantity);
            }).catch(function (error) {
                console.log(error);
            });
        },

        putProductQuantity(valueToAdd){
            console.log("PUT")
            let $this = this;
            tdtdapi.put( '/cart/products/me', querystring.stringify({
                    product: $this.id,
                    quantity: ($this.quantity + valueToAdd)
                }), configs
            ).then(function (response) {
                console.log(response);
                $this.setQuantity(response.data.quantity);
            }).catch(function (error) {
                console.log(error);
            });
        },

        deleteProductQuantity(){
            console.log("DELETE")
            let $this = this;
            tdtdapi.delete( '/cart/products/me/' + this.id, configs
            ).then(function (response) {
                console.log(response);
                $this.setQuantity(0);//todo: use v-show to hide product when (this.quantity === 0)
            }).catch(function (error) {
                console.log(error);
            });
        },

        emitChanged() {
            this.$emit( "productChanged" );
        },

        incrementQuantity(){
            this.addQuantity(1);
        },

        decrementQuantity( product ){
            console.log(product)
            // if( this.quantity >= 1 ){
            //     this.addQuantity(-1);
            // }
        },

        getPriceWithoutSymbols(){
            //todo: if price contains currency, when need to get only the value
            return this.priceWithCurrency;
        },

        setQuantity( quantity ){
            if( this.isProductRefreshAuto ){
                this.quantity = quantity;
            }
            this.emitChanged();
        }
    },

    computed: {
        totalPrice: function(){
            return (this.quantity * this.price).toFixed(2);
        }
    }
};

我看到的一个错误是,你有驼峰命名的道具,例如 priceWithCurrency,对于这些道具,你必须在传入模板时使用 kebab-case,如 here 所述:

template: "<div><h3>Cart:</h3>" +
    '<product @product-changed="updateProductsCart(product)"' +
    'style="display: inline-block; max-width: 90px;" v-for="product in products"' +
    ':id="product.id" :name="product.name" :price-with-currency="product.priceWithCurrency"' +
    ':init-quantity="product.initQuantity" :picture="product.picture" :has-deleted-btn="true"' +
    ':is-product-refresh-auto="false"></product>' +
"</div>",

问题是我们必须用 props.

刷新 Product 的 data

基本上当父级(这里是 Cart 组件)用道具(这里是 initQuantity)改变产品的数量时,我们必须告诉产品实例他必须用他的道具(这里是数量)改变数据(这里是数量)(initQuantity) .

所以我们必须在 Product 组件的末尾添加一个 watch :

    computed: {
        ...
    },

    watch: {
        initQuantity( newQuantity ){
            this.quantity = newQuantity;
        }
    }

我找到了答案here