使用 setTimeout 函数时在 Vue 中使用 v-show 或 v-if 切换可见性

Toggle visibility using v-show or v-if in Vue while using a setTimeout function

我正在使用 Vue2。我有一个表格。单击提交后,我想在 X 时间内显示“正在加载”Div。在这段 X 时间后,我想再次加载表单。简而言之,点击后,切换可见性,执行某些代码并等待一定时间后,再次切换。

我有两个 Div:

<div v-if="this.isHidden">
 LOADING....
</div>

<div v-if="!this.isHidden"> <!--or v-else -->
  <form @submit.prevent="">
  <!--Fields-->
  <button @click="updateProduct(product)" type="button">Submit</button>
  </form>
</div>

加载时,仅显示“内容”(isHidden = false)。 当执行 updateProduct() 方法时,我希望 div“LOADING”出现 X 秒(isHidden=true),而“CONTENT”div 必须隐藏。然后在 setTimeout 函数中执行一些代码后,我希望它们再次切换 (isHidden = false)。

data: function() {
   return {
     //isHidden is initialized as false
     isHidden: false,
   };
},

我的方法是这样的:

updateProduct(product){
  this.isHidden = true;
  alert(this.isHidden + 'This correctly shows true. CONTENT correctly toggles and HIDES. LOADING also works correctly and APPEARS.');
  //I want to delay the following code with setTimeout so that I am able to control for how long I want to show LOADING
  setTimeout(function(){
    //do a bunch of tasks that work correctly... 
    axios.post('/api/product/' + product.id, data)
       .then(function (response) {
       console.log(response);
     }).catch(function (error) {
       console.log(error);            
     });

    //After all my code is executed, I am still inside the setTimeout function inside the updateProduct method so now i do this:
    this.isHidden = false;
    alert(this.isHidden + ' This correctly shows false BUT DIVS DO NOT UPDATE ANYMORE, I am stuck with the LOADING div');
   //although my code works fine and the alert shows the correct value for isHidden, my view is stuck in LOADING

  }, 2000);
}

我尝试移动 this.isHidden = false;在 setTimeout 函数之外,但它仍然不会“切换”可见性。

我也尝试过使用 v-if 而不是 v-show,同样的行为。

只需使用 V-else

<div v-if="!this.isHidden"> <!--or v-else -->
  <form @submit.prevent="">
  <!--Fields-->
  <button @click="updateProduct(product)" type="button">Submit</button>
  </form>
</div>

<div v-else>
<div v-if="this.isHidden">
 LOADING....
</div>
</div>

您的主要问题是 this 在 setTimeout 回调中

因为你使用 function() {} 这不是你想要的 this

要么使用箭头符号setTimeout(() => {}, 2000)

updateProduct(product) {
  this.isHidden = true;
  setTimeout(() => {
    //do a bunch of tasks that work correctly... 
    axios.post('/api/product/' + product.id, data)
      .then(function(response) {
        console.log(response);
      }).catch(function(error) {
        console.log(error);
      });
    this.isHidden = false;
  }, 2000);
}

或者,如果您害怕箭头符号 setTimeout(function() {}.bind(this), 2000)

updateProduct(product) {
  this.isHidden = true;
  setTimeout(function() {
    //do a bunch of tasks that work correctly... 
    axios.post('/api/product/' + product.id, data)
      .then(function(response) {
        console.log(response);
      }).catch(function(error) {
        console.log(error);
      });
    this.isHidden = false;
  }.bind(this), 2000);
}

作为旁注,不要使用 alert 进行调试 - 它会阻止 javascript 的执行,并可能导致不可靠的调试结果