VueJS 深度观察者 - 特定于多个对象 属性
VueJS deep watcher - specific property on multiple objects
问题
我有一个包含多个对象的 "products" 数组。每个产品对象都包含 属性 "price"。我想在每个产品中查看此 属性 以了解可能的更改。当用户在输入框中更改价格时,我使用它来计算佣金价格。
我的产品数组如下所示;
[
0: {
name: ...,
price: ...,
commission: ...,
},
1: {
name: ...,
price: ...,
commission: ...,
},
2: {
name: ...,
price: ...,
commission: ...,
},
...
...
...
]
我的代码
我试过了,但它没有检测到任何变化,除了首次加载产品时;
watch : {
// Watch for changes in the product price, in order to calculate final price with commission
'products.price': {
handler: function (after, before) {
console.log('The price changed!');
},
deep : true
}
},
产品是这样加载的;
mounted: async function () {
this.products = await this.apiRequest('event/1/products').then(function (products) {
// Attach reactive properties 'delete' & 'chosen' to all products so these can be toggled in real time
for (let product of products) {
console.log(product.absorb);
Vue.set(product, 'delete', false);
Vue.set(product, 'chosen', product.absorb);
}
console.log(products);
return products;
})
}
我看过的其他问题
这个正在尝试观看尚不存在的 属性。
这个正在监视另一个组件的变化。
你不能真的 deep-watch products.price
,因为价格是单个产品的 属性,而不是产品数组。
声明式观察器对数组有问题,如果您尝试在观察表达式中使用索引,例如 products[0].price
,您会收到来自 Vue 的警告
[Vue warn]: Failed watching path: “products[0].price”. Watcher only accepts simple dot-delimited paths. For full control, use a function instead.
这意味着您可以将 programmatic watch 与函数一起使用,但解释得不是很清楚。
这是在您的场景中执行此操作的一种方法
<script>
export default {
name: "Products",
data() {
return {
products: []
};
},
mounted: async function() {
this.products = await this.apiRequest('event/1/products')...
console.log("After assigning to this.products", this.products);
// Add watchers here, using a common handler
this.products.forEach(p => this.$watch(() => p.price, this.onPriceChanged) );
// Simulate a change
setTimeout(() => {
console.log("Changing price");
this.products[0].price= 100;
}, 1000);
},
methods: {
onPriceChanged(after, before) {
console.log(before, after);
}
}
};
</script>
这是我的测试Codesandbox(我使用颜色而不是价格,因为测试中没有价格api)
问题
我有一个包含多个对象的 "products" 数组。每个产品对象都包含 属性 "price"。我想在每个产品中查看此 属性 以了解可能的更改。当用户在输入框中更改价格时,我使用它来计算佣金价格。
我的产品数组如下所示;
[
0: {
name: ...,
price: ...,
commission: ...,
},
1: {
name: ...,
price: ...,
commission: ...,
},
2: {
name: ...,
price: ...,
commission: ...,
},
...
...
...
]
我的代码
我试过了,但它没有检测到任何变化,除了首次加载产品时;
watch : {
// Watch for changes in the product price, in order to calculate final price with commission
'products.price': {
handler: function (after, before) {
console.log('The price changed!');
},
deep : true
}
},
产品是这样加载的;
mounted: async function () {
this.products = await this.apiRequest('event/1/products').then(function (products) {
// Attach reactive properties 'delete' & 'chosen' to all products so these can be toggled in real time
for (let product of products) {
console.log(product.absorb);
Vue.set(product, 'delete', false);
Vue.set(product, 'chosen', product.absorb);
}
console.log(products);
return products;
})
}
我看过的其他问题
你不能真的 deep-watch products.price
,因为价格是单个产品的 属性,而不是产品数组。
声明式观察器对数组有问题,如果您尝试在观察表达式中使用索引,例如 products[0].price
,您会收到来自 Vue 的警告
[Vue warn]: Failed watching path: “products[0].price”. Watcher only accepts simple dot-delimited paths. For full control, use a function instead.
这意味着您可以将 programmatic watch 与函数一起使用,但解释得不是很清楚。
这是在您的场景中执行此操作的一种方法
<script>
export default {
name: "Products",
data() {
return {
products: []
};
},
mounted: async function() {
this.products = await this.apiRequest('event/1/products')...
console.log("After assigning to this.products", this.products);
// Add watchers here, using a common handler
this.products.forEach(p => this.$watch(() => p.price, this.onPriceChanged) );
// Simulate a change
setTimeout(() => {
console.log("Changing price");
this.products[0].price= 100;
}, 1000);
},
methods: {
onPriceChanged(after, before) {
console.log(before, after);
}
}
};
</script>
这是我的测试Codesandbox(我使用颜色而不是价格,因为测试中没有价格api)