vue.js $监视对象数组

2eafrhcq  于 2023-02-13  发布在  Vue.js
关注(0)|答案(5)|浏览(196)
mounted: function() {
  this.$watch('things', function(){console.log('a thing changed')}, true);
}

things是对象[{foo:1}, {foo:2}]的数组
$watch检测对象的添加或删除,但不检测对象的值的更改。我该怎么做?

vqlkdk9b

vqlkdk9b1#

您应该传递一个对象而不是布尔值options,因此:

mounted: function () {
  this.$watch('things', function () {
    console.log('a thing changed')
  }, {deep:true})
}

或者,您可以将监视器设置到vue示例中,如下所示:

new Vue({
  ...
  watch: {
    things: {
      handler: function (val, oldVal) {
        console.log('a thing changed')
      },
      deep: true
    }
  },
  ...
})

demo(http://jsfiddle.net/q3zd4fmv/)

iq3niunx

iq3niunx2#

如果有人需要获取数组中已更改的项,请选中它:
JSFiddle Example
帖子示例代码:

new Vue({
  ...
  watch: {
    things: {
      handler: function (val, oldVal) {
        var vm = this;
        val.filter( function( p, idx ) {
            return Object.keys(p).some( function( prop ) {
                var diff = p[prop] !== vm.clonethings[idx][prop];
                if(diff) {
                    p.changed = true;                        
                }
            })
        });
      },
      deep: true
    }
  },
  ...
})
gwbalxhn

gwbalxhn3#

有一个更简单的方法可以在没有深度观察的情况下观察阵列中的物品:应用计算值的

{
  el: "#app",
  data () {
    return {
      list: [{a: 0}],
      calls: 0,
      changes: 0,
    }
  },
  computed: {
    copy () { return this.list.slice() },
  },
  watch: {
    copy (a, b) {
      this.calls ++
      if (a.length !== b.length) return this.onChange()
      for (let i=0; i<a.length; i++) {
        if (a[i] !== b[i]) return this.onChange()
      }
    }
  },
  methods: {
    onChange () {
      console.log('change')
      this.changes ++
    },
    addItem () { this.list.push({a: 0}) },
    incrItem (i) { this.list[i].a ++ },
    removeItem(i) { this.list.splice(i, 1) }
  }
}

https://jsfiddle.net/aurelienlt89/x2kca57e/15/
我们的想法是构建一个计算值copy,它包含我们想要检查的内容。计算值很神奇,只对实际读取的属性(这里是list.slice()中读取的list的项)放置监视器。copy监视器中的检查实际上几乎毫无用处(可能除了奇怪的极端情况),因为计算值已经非常精确。

ryoqjall

ryoqjall4#

您可以使用$watch('arr.0', () => {})$watch('dict.keyName', () => {})单独监视数组或字典中的每个元素的更改
来自www.example.comhttps://v2.vuejs.org/v2/api/#vm-watch:
注意:当改变(而不是替换)一个对象或数组时,旧值将与新值相同,因为它们引用相同的对象/数组。Vue不保留改变前值的副本。
然而,你可以独立地迭代dict/array和$watch每一项。例如,$watch('foo.bar')-这会监视对象'foo'的属性'bar'的变化。
在这个例子中,我们观察arr_of_numbers中的所有项,以及arr_of_objects中所有项的'foo'属性:

mounted() {
        this.arr_of_numbers.forEach( (index, val) => {
            this.$watch(['arr_of_numbers', index].join('.'), (newVal, oldVal) => {
                console.info("arr_of_numbers", newVal, oldVal);
            });
        });

        for (let index in this.arr_of_objects) {
            this.$watch(['arr_of_objects', index, 'foo'].join('.'), (newVal, oldVal) => {
                console.info("arr_of_objects", this.arr_of_objects[index], newVal, oldVal);
            });
        }

    },
    data() {
        return {
            arr_of_numbers: [0, 1, 2, 3],
            arr_of_objects: [{foo: 'foo'}, {foo:'bar'}]
        }
    }
shyt4zoc

shyt4zoc5#

如果要渲染和排列渲染项目并查看其更改,可以执行以下操作:
1.创建新组件:

const template = `<div hidden></div>`
export default {
    template,
    props: ['onChangeOf'],
    emits: ['do'],
    watch: {
        onChangeOf: {
            handler(changedItem) {
                console.log('works')
                this.$emit('do', changedItem)
            },
            deep: true
        }
    },
}

1.注册该组件:

Vue.component('watcher', watcher)

1.在foreach渲染中使用它:

<tr v-for="food in $store.foods" :key="food.id">
    <watcher :onChangeOf="food" @do="(change) => food.name = 'It works!!!'"></watcher>
</tr>

相关问题