Vue Js - 为什么在某些情况下对数据的更改不会更新视图

jco*_*met 2 vue.js vuejs2

使用下面的代码,如果单击添加,您可以在控制台中看到值更改,但视图未更新.

new Vue({
  el: '#app',
  data: {
    dateValue: new Date(2017,0,1),    
  },
  methods: {
    addOne: function () {    	
      this.dateValue.setDate(this.dateValue.getDate() + 1);    
      console.log('new date',this.dateValue);
    }
  }
});
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
<div id="app">
    Date Value : {{ dateValue }}<br />
    
    <button v-on:click="addOne">Add One</button> <br />
</div>
Run Code Online (Sandbox Code Playgroud)

如果我引入简单的整数值并将其显示在日期旁边,它将正常工作并导致日期值也正确更新.

new Vue({
  el: '#app',
  data: {
    dateValue: new Date(2017,0,1), 
    intValue: 0
  },
  methods: {
    addOne: function () {    	
      this.dateValue.setDate(this.dateValue.getDate() + 1);  
      this.intValue++;
      
      console.log('new date',this.dateValue);
    }
  }
});
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>

<div id="app">
    Date Value : {{ dateValue }}   Int Value : {{ intValue }}<br />
    
    <button v-on:click="addOne">Add One</button> <br />
</div>
Run Code Online (Sandbox Code Playgroud)

我已经开始以各种方式设置日期,我只是不明白这里发生了什么.某种程度上没有检测到日期的变异.我希望有人可以对此有所了解.

rai*_*7ow 5

这条线......

this.dateValue.setDate(this.dateValue.getDate() + 1);
Run Code Online (Sandbox Code Playgroud)

...更改存储在其中的Date对象的"内容" this.dateValue,但不更改对象(引用)本身.实质上,它this.dateValue具有与以前相同的值,因此相应的机制不会检测到任何更改,也不会触发视图更新.现在与这个片段进行比较:

new Vue({
  el: '#app',
  data: {
    dateValue: new Date(2017,0,1),    
  },
  methods: {
    addOne: function () {    	
      this.dateValue = new Date(
        this.dateValue.setDate(this.dateValue.getDate() + 1)
      );
      console.log('new date',this.dateValue);
    }
  }
});
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
<div id="app">
    Date Value : {{ dateValue }}<br />
    
    <button v-on:click="addOne">Add One</button> <br />
</div>
Run Code Online (Sandbox Code Playgroud)

随着新的日期对象是在每个调用创建addOne(),改变检测到,并且相应的视图进行更新.


你可能会问为什么你的第二个片段有效?同样,答案是关于变化检测.随着intValue值的改变,它足以触发整个组件的重新渲染(在这种特定情况下为app实例).

是的,在为更改后的状态构建新的Virtual DOM时,VueJS会检索所有属性的值 - 而不仅仅是已更改的属性.这是将应用于真实DOM的新旧V-DOM之间的区别.