【问题标题】:VueJS deep watcher - specific property on multiple objectsVueJS 深度观察器 - 多个对象的特定属性
【发布时间】:2019-10-27 05:23:23
【问题描述】:

问题

我有一个包含多个对象的“产品”数组。每个产品对象都包含属性“价格”。我想在每个产品中查看此属性以了解可能的更改。当用户在输入框中更改价格时,我使用它来计算佣金价格。

我的产品数组如下所示;

[
  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;
            })
        }

我看过的其他问题 Vue.js watching deep properties 这个试图观察一个尚不存在的属性。 VueJs watching deep changes in object 这个正在监视另一个组件的变化。

【问题讨论】:

    标签: javascript vue.js vuejs2 watch


    【解决方案1】:

    你不能真正深入观察products.price,因为价格是单个产品的属性,而不是产品数组。

    声明式观察者对数组有问题,如果您尝试在观察表达式中使用索引,例如products[0].price,您会收到来自 Vue 的警告

    [Vue 警告]:观看路径失败:“products[0].price”。 Watcher 只接受简单的点分隔路径。要完全控制,请改用函数。

    这意味着您可以将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 中没有价格)

    【讨论】:

    • 很好,这似乎可以满足我的需要 - 谢谢!
    猜你喜欢
    • 2018-07-12
    • 2023-04-02
    • 2017-10-19
    • 1970-01-01
    • 2019-07-12
    • 2021-11-08
    • 2015-11-13
    • 2017-07-12
    • 1970-01-01
    相关资源
    最近更新 更多