为什么在prop不变的情况下会触发Vue.js中的watch方法?

时间:2019-01-30 19:40:12

标签: vue.js

我了解,当更改/重新分配要监视的属性/数据时,将触发该属性/数据的监视方法。

但是,在此代码段中,尽管initTasks未被更改(或看起来没有改变),但initTasks的watch方法被触发。

此代码段应在每次添加任务时增加“估计”。但是,估计不会增加,因为initTask的watch方法每次都会覆盖估计。

https://jsfiddle.net/akosipax/1qtLfyn4/43/

Vue.component('customcomponent', {
	props: ['initTasks', 'initEstimate'],
  data()  {
  	return {
    	tasks: [],
      estimate: 0,
    }
  },
  
  template: `
  	<div>
    	<ul>
      	<li v-for="(task, index) in tasks" :key="index">
          {{task.text}}
        </li>
      </ul>
      <p>It will take you {{estimate}} hours to do all of these!</p>
      <button @click="addTask">Add task</button>
   </div>
  `,
  
  methods: {
  	initialize() {
      this.tasks = this.initTasks;
      this.estimate = this.initEstimate;
    },
    
    addTask() {
    	Vue.set(this.tasks, this.tasks.length, {
      	text: "Do this new task"
      });
      
      this.estimate++;
    }
  },
  
  watch: {
  	initTasks: function(oldval, newval) {
    	console.log('watch for initTasks triggered!');
      this.initialize();
    }
  },
  
  mounted() {
  	console.log('mounted() triggered!')
  	this.initialize();
  },
  
  created() {
  	console.log('created() triggered!')
  },
  
  updated() {
    console.log('updated() triggered!')
  },
  
  destroyed() {
    console.log('updated() triggered!')
  }
});

new Vue({
  el: "#app",
  data: {
    tasks: [
      { text: "Learn JavaScript"},
      { text: "Learn Vue"},
      { text: "Play around in JSFiddle"},
      { text: "Build something awesome"}
    ],
    estimate: 5
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <customcomponent :init-tasks="tasks" :init-estimate="estimate"></customcomponent>
</div>

1 个答案:

答案 0 :(得分:1)

如果您将initialize方法更改为:

    initialize() {
      this.tasks = this.initTasks.slice();
      this.estimate = this.initEstimate;
    }

一切都会正常。我认为监视程序已被触发,因为当您更改任务数组时,initTasks也将更改,因为数组为Mutable

如果您使用的是es2015及更高版本,则可以执行以下操作:

this.tasks = ...[this.initTasks];

this.tasks = Array.from(this.initTasks);