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