Vue - 组件道具不能正常观察对象

时间:2017-08-07 16:25:35

标签: javascript vue.js vuejs2

我的根目录中有两个对象 - objnewObj。我使用obj观看deep: true对象的更改,并根据更改相应更新newObj。

在我的vue调试器中,newObj似乎按预期更新,但组件没有执行for循环计数。或者,如果我尝试{{ newObj }},它只记录第一次更新。

我尝试重新创建问题on this Fiddle

我的HTML:

<div id="app">
  <button @click="appendTo">Append</button>
  <my-comp v-bind:new-obj="newObj"></my-comp>
</div>

和vue:

new Vue({
  el: '#app',
  data: {
    obj: {},
    newObj: {}
  },

  methods: {
    appendTo() {
      if (typeof this.obj[1] === 'undefined') {
        this.$set(this.obj, 1, {})
      }

      var randLetter = String.fromCharCode(Math.floor(Math.random() * (122 - 97)) + 97);
         this.$set(this.obj[1], randLetter, [ [] ])
      }
    },

  watch: {
    obj: {
        handler(obj) {
        var oldKeys = Object.keys(obj)
        var newKeys = Object.keys(this.newObj);

        var removedIndex = newKeys.filter(x => oldKeys.indexOf(x) < 0 );
        for (var i = 0, len = removedIndex.length; i < len; i++) {
          delete this.newObj[removedIndex[i]]
        }

        oldKeys.map((key) => {
          if (this.newObj.hasOwnProperty(key)) {
            var newInnerKeys = Object.keys(this.newObj[key]);
            var oldInnerKeys = Object.keys(obj[key]);

            var additions = oldInnerKeys.filter(x => newInnerKeys.indexOf(x) < 0);

            for (var i = 0, len = additions.length; i < len; i++) {
              // here
              this.$set(this.newObj[key], additions[i], [ [] ]);
            }

            var deletions = newInnerKeys.filter(x => oldInnerKeys.indexOf(x) < 0);
            for (var i = 0, len = deletions.length; i < len; i++) {
              delete this.newObj[key][deletions[i]]
            }

          } else {
            this.newObj[key] = {}
            for (var innerKey in obj[key]) {
              this.$set(this.newObj, key, {
                [innerKey]: [ [] ]
              });
            }
          }

          console.log(obj);
          console.log(this.newObj)
        });
      },
      deep: true
    }
  }
})

Vue.component('my-comp', {
    props: ['newObj'],
  template: `
        <div>
        <div v-for="item in newObj">
            test
      </div>
    </div>
  `
})

1 个答案:

答案 0 :(得分:3)

您的数据newObj有一个由vue定义的getter和setter。调用setter时,将重新呈现UI。更改newObj参考时会触发设置器,而不会更改其值。我的意思是:

this.newObj = {} // triggered

this.newObj['key'] = 'value' // not triggered

您可以在属性this.newObj上添加深度观察者。或者通过一个技巧改变它的参考:

this.newObj = Object.assign({}, this.newObjec);

创建对象newObject的副本。

这是小提琴更新。

https://jsfiddle.net/749nc5d2/