为什么观看对象未在vue

时间:2017-05-30 10:49:51

标签: javascript vue.js

我知道有很多像这样的问题,但这个问题有点不同。我看了一下reactivity in depth并认为我对这个问题有一个公平的理解,但有一点我无法理解,不过这是:

TL;博士

为什么在使用currentValue = Object.assign=({}, currentValue, initValue)进行初始化但未使用直接分配currentValue = initValue;进行初始化时,已观察的属性寄存器会发生变化?

我的vue组件模型上有一个注册对象scoreRules

mounted挂钩中,

  1. 我使用

    重新初始化模型scoreRules

    this.$data.scoreRules = initScoreRules;

    initScoreRules作为道具传入,但我将其声明为本地 以下变量用于此问题的目的)。

  2. 观看scoreRules进行更改并记录"得分已更改"当对象改变时。

  3. 此代码段显示了此方案

    
    
    new Vue({
      el: '#app',
      data() {
        return {
          scoreRules: {
            type: "number",
            minimum: null,
            maximum: null
          }
        }
      },
      mounted() {
      let initScoreRules = {type: "number"};
        this.$data.scoreRules = initScoreRules;
        this.$watch('scoreRules', ()=>{console.log("score has been changed")}, {deep: true});
      }
    });
    
    <html>
    
    <head>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.6/vue.js"></script>
    </head>
    
    <body>
      <div id="app">
        <span>Minimum score</span>
        <input type="number" name="minimumScore" v-model.number="scoreRules.minimum" />
    </body>
    
    </html>
    &#13;
    &#13;
    &#13;

    现在,当我在输入中输入内容时,手表不会捕获此更改,并且没有任何内容记录到控制台。

    如果我现在重新初始化scoreRules使用 this.$data.scoreRules = Object.assign({}, this.$data.scoreRules, initScoreRules);

    &#13;
    &#13;
    new Vue({
      el: '#app2',
      data() {
        return {
          scoreRules: {
            minimum: null
          }
        }
      },
      mounted() {
        let initScoreRules = {};
        this.$data.scoreRules = Object.assign({}, this.$data.scoreRules,  initScoreRules);
        this.$watch('scoreRules', () => {
          console.log("score has been changed")
        }, {
          deep: true
        });
      }
    });
    &#13;
    <html>
    
    <head>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.6/vue.js"></script>
    </head>
    
    <body>
      <div id="app2">
        <span>Minimum score</span>
        <input type="number" v-model.number="scoreRules.minimum" />
      </div>
    </body>
    
    </html>
    &#13;
    &#13;
    &#13;

    注册更改并将输出记录到控制台。为什么?我怀疑它与JS本身的内部有关,但我不确定究竟是怎么做的。

1 个答案:

答案 0 :(得分:1)

初始对象包含属性minimummaximum。然后,在mounted中执行此操作:

let initScoreRules = {type: "number"};
this.$data.scoreRules = initScoreRules;

这意味着现在scoreRules对象没有这些属性。

Vue只能观察属性的变化:

  • data()中预先定义(您已在mounted中执行但未执行此操作)
  • 使用Vue.set() / this.$set()
  • 进行设置
  • 出现在分配给被动财产的对象上。

最后一点也解释了为什么第二个例子有效:在这里,基本上你这样做(抛弃了Object.assign冗长,因为它分散了注意力):

this.$data.scoreRules = { minimum: null }; 

此属性将被反应。

在这里阅读更多内容:

https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats