Vue.js函数多次调用

时间:2018-07-20 12:06:11

标签: vue.js

运行代码,然后在浏览器的控制台中查看。您会看到函数“ formatName()”被多次调用。为什么?我不更新种族数据。 但是,如果我将函数“ amIStarted()”更改为“返回开始<5”,则它将执行2次,这是正确的。 (对不起,我的英语)

https://jsfiddle.net/a496smx2/48/

var stopwatch = new Vue({
    el: "#stopwatch",
  data: {
    time: 1
  },
  created: function() {
    setInterval(function(){
        stopwatch.time++;
    }, 1000);
  }
})

var race = new Vue({
  el: "#race",
  data: {
        startList: [
        {name: "John", start: 3},
        {name: "Mike", start: 7},
        {name: "Gabe", start: 333},
    ],
  },
  methods: {
    amIStarted: function(start) {
        return start < stopwatch.time;
    },
    formatName: function(name) {
        console.log("I was called.")
        return 'Mr. '+name;
    }
  }
});

<div id="stopwatch" ><h4>Time: <span class="gold" >{{time}}</span></h4></div>

<small>Yellow color means the person started</small>

<div id="race" >
  <div v-for="oneStart in startList" :class="{gold : amIStarted(oneStart.start)}" >
    {{formatName(oneStart.name)}} will start when time is more then {{oneStart.start}}
  </div>
  <br><br>
</div>

3 个答案:

答案 0 :(得分:1)

  

函数“ formatName()”被多次调用。为什么?

因为,您添加了一个不断变化的变量,并检查是否添加了类:class="{gold : amIStarted(oneStart.start)}",并在每个chanve vue中重新加载了函数所在的部分,并再次调用它。

var stopwatch = new Vue({
    el: "#stopwatch",
  data: {
    time: 1
  },
  created: function() {
    setInterval(function(){
        stopwatch.time++;
    }, 1000);
  }
})

var race = new Vue({
  el: "#race",
  data: {
        startList: [
        {name: "John", start: 3},
        {name: "Mike", start: 7},
        {name: "Gabe", start: 333},
    ],
  },
  methods: {
    amIStarted: function(start) {
        return start < stopwatch.time;
    },
    formatName: function(name) {
        console.log("I was called.")
        return 'Mr. '+name;
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>


<div id="stopwatch" ><h4>Time: <span class="gold" >{{time}}</span></h4></div>

<small>Yellow color means the person started</small>

<div id="race" >
<div>
  <div v-for="oneStart in startList"  >
    {{formatName(oneStart.name)}} will start when time is more then {{oneStart.start}}
  </div>
  <br><br>
  </div>
</div>

这是流程

https://vuejs.org/images/data.png enter image description here

还有许多其他方法可以实现您想做的事情。请检查那些。

答案 1 :(得分:0)

您正在寻找computed properties而不是方法。它们将被优化,以便仅在依赖于更改的道具时才运行它们。每次发生更新时都会运行方法,这可能与鼠标移动的频率相同,这取决于您的应用程序结构和复杂性。

答案 2 :(得分:0)

每次渲染模板时都会调用模板中嵌入的功能或过滤器,因此,每次更新时间,该功能(作为每个名称一次)将作为重新渲染的一部分运行。

只要您的方法没有不良副作用,通常就可以了!但是,如果您可能一次遇到很多问题并开始遇到性能问题,则可以切换到计算函数。

仅当计算函数依赖于数据时,才会调用它们。您不能将参数传递给计算函数,因此,与其单独处理每个单独的名称,不如将其一次性修改整个名称列表:

var stopwatch = new Vue({
  el: "#stopwatch",
  data: {
    time: 1
  },
  created: function() {
    setInterval(function() {
      stopwatch.time++;
    }, 1000);
  }
})

var race = new Vue({
  el: "#race",
  data: {
    startList: [{
        name: "John",  start: 3
      }, {
        name: "Mike",  start: 7
      }, {
        name: "Gabe",  start: 333
      }
    ]
  },
  computed: {
    formattedList() {
    console.log("Computed function ran");
      let arr = [];
      for (let oneStart of this.startList) {
        arr.push({
          formattedName: 'Mr. ' + oneStart.name,
          start: oneStart.start        
        })
      }
      return arr
    }
  },
  methods: {
    amIStarted: function(start) {
      return start < stopwatch.time;
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>

<div id="stopwatch">
  <h4>Time: <span class="gold">{{time}}</span></h4>
</div>

<small>Yellow color means the person started</small>

<div id="race">
  <div v-for="oneStart in formattedList" :class="{gold : amIStarted(oneStart.start)}">
    {{oneStart.formattedName}} will start when time is more then {{oneStart.start}}
  </div>
  <br><br>
</div>

另一种方法是修改beforeMount()created()块中的数据,但这仅在您确定输入数据在组件的使用期限内不会改变的情况下才适用。