如何比较以前和更新的道具Vue?

时间:2018-08-28 18:58:41

标签: javascript vue.js vuejs2

我从道具中获得一个数组,并且当数组的长度改变时,我应该触发一个函数。由于文档的缘故,我应该使用以下构造“ handler:function(val,oldVal)”,但是它将返回新的长度。

props: ['array']
watch: {
  array: function(val, oldVal) { // watch it
    console.log('Prop changed: ', val, ' | was: ', oldVal) // it always returns the new array 
  }
}

也许我应该使用一些生命周期挂钩?

2 个答案:

答案 0 :(得分:0)

大多数JavaScript的内置数组功能都会对数组进行突变,而不是创建新数组。 Vue将检测到更改,但基本行为保持不变,对该数组进行修改。

例如,array.push(17)将新值添加到同一数组的末尾,而不创建新数组。

如果修改数组,它将通知watch函数,但是'new'数组与原始数组只是同一对象。因此,Vue 正在向您传递旧数组,您刚刚修改了该数组。 Vue不存储该数组原始状态的副本。

来自the docs

  

注意:当更改(而不是替换)对象或数组时,旧值将与新值相同,因为它们引用相同的对象/数组。 Vue不会保留突变前值的副本。

如果您只关心长度,可以执行以下操作:

computed: {
    arrayLength () {
        return this.array.length
    }
},

watch: {
    arrayLength (newLength, oldLength) {
        // ...
    }
}

或更直接地:

watch: {
    'array.length' (newLength, oldLength) {
        // ...
    }
}

如果您确实需要旧数组,那么您要么必须传递一个副本作为prop值,要么在您的组件内复制一个副本。

答案 1 :(得分:0)

我的代码示例没有任何问题。下面是一个有效的示例。

  • 确定要传递作为道具的数组吗?
  • 确定要正确更改数组吗?

签出Vuejs Docs - Array Caveats

foo
    Vue.component('child', {
        template: '<div>Array length is {{ array.length }}</div>',
        props: {
            array: {
                type: Array,
                default: () => [],
            },
        },
        watch: {
            array: function(val, oldVal) {
                alert(`changed from ${oldVal.length} to ${val.length}`);
            },
        },
    });

    new Vue({
        el: '#app',
        data() {
            return {
                arr: [1, 2, 3],
            };
        },
        mounted() {
            setTimeout(this.updateArr, 3000);
        },
        methods: {
            updateArr() {
                this.arr = [1, 2, 3, 4];
            },
        },
    });