【问题标题】:Vuejs - Why does the trigger of a method also trigger an unrelated method via v-ifVuejs - 为什么一个方法的触发也会通过v-if触发一个不相关的方法
【发布时间】:2021-02-12 08:38:34
【问题描述】:

我创建了一个做两件事的组件。

功能 1:在蓝色方块和红色方块之间切换按钮循环。

功能2:在输入区域输入5个或更多字符显示绿色方块。

<template>
  <div id="app">
    <div id="container1">
      <h2>Container 1</h2>
      <h5>Toggle Button to Change Box</h5>
      <div class="box1" v-if="isBlueBoxDisplayed()">
        <span>1a</span>
      </div>
      <div class="box2" v-else>
        <span>1b</span>
      </div>
      <button @click="toggleBlueBox">Toggle Blue Box</button>
    </div>
    <div id="container2">
      <h2>Container 2</h2>
      <h5>Type 5 or more characters for Green Box</h5>
      <input
        placeholder="Type 5 characters"
        v-model="userInput"
        @input="validateInputForGreenBox()"
      />
      <div class="box3" v-if="displayGreen">
        <span>2</span>
      </div>
    </div>
    <div id="container3">
      <p>
        Why does <span class="bold">isBlueBoxDisplayed()</span> method trigger
        when <span class="bold">validateInput()</span> is triggered?
      </p>
      <p>(see console for confirmation of this)</p>
    </div>
  </div>
</template>
<script>
export default {
  name: "App",
  data() {
    return {
      displayBlue: false,
      displayGreen: false,
      userInput: "",
    };
  },
  methods: {
    toggleBlueBox() {
      this.displayBlue = !this.displayBlue;
    },
    isBlueBoxDisplayed() {
      console.log("isBlueBoxDisplayed() method activated!");
      if (this.displayBlue) {
        return true;
      }
      return false;
    },
    validateInputForGreenBox() {
      console.log("validateInputForGreenBox() method Hit!");
      if (this.userInput.length > 4) {
        return (this.displayGreen = true);
      }
      this.displayGreen = false;
    },
  },
};
</script>
<style>
#app {
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
  display: flex;
  justify-content: space-between;
  width: 100%;
}

#container1,
#container2 {
  border-right: 2px solid grey;
}

div > span {
  color: white;
}

.bold {
  font-weight: 600;
}
.box1 {
  width: 100px;
  height: 100px;
  background-color: blue;
}

.box2 {
  width: 100px;
  height: 100px;
  background-color: red;
}

.box3 {
  width: 100px;
  height: 100px;
  background-color: green;
}
</style>

这里的沙盒: https://codesandbox.io/s/gifted-matsumoto-lq2mj?file=/src/App.vue

问题:

这两个功能彼此无关。然而,当用户输入输入区域时(它应该触发 validateInputForGreenBox() 方法),它会触发 isBlueBoxDisplayed() 方法(不应该触发)。

在我拥有的大型应用程序中,这会导致一些性能问题,从而触发多个不相关的方法。那么为什么会这样呢?有没有什么办法可以避免不相关的方法触发?

【问题讨论】:

  • 这可能是因为每次页面上发生任何更改时,它都会评估该方法调用的真实性。我猜这只是 Vue 反应性的一部分,虽然不太确定

标签: javascript vue.js


【解决方案1】:

虽然是一个简单的答案,但我已经多次看到斗争。

这里的问题是你传递给你的事件的函数会被立即调用,几乎就像一个 IIFE。由于页面上存在v-if,您正在导致再次触发方法的重排。

简答:

将函数传递给事件时不要使用()

好:

@input="validateInputForGreenBox"

不好:

@input="validateInputForGreenBox()"

and the fiddle for proof

【讨论】:

  • 我写了同样的答案?UP。
  • 在您的小提琴中,蓝色框的按钮不起作用。我认为在这种情况下你应该使用计算属性而不是方法
  • 这一切都很好,谢谢。但是跟进:如果我们需要将参数传递给函数怎么办?例如,该函数附加到一个列表项,我们希望将该列表项的索引传递给该函数。在这种情况下,我必须这样做:@input="validateInputForGreenBox(index)".
  • 只是测试你的小提琴,你的小提琴中的 isBlueBoxDisplayed 不再切换蓝色/红色框。我猜是因为您删除了()。有什么办法可以让它再次工作,同时保持你的答案正确?
猜你喜欢
  • 1970-01-01
  • 2011-05-28
  • 2011-02-18
  • 2018-07-11
  • 2013-06-01
  • 2013-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多