【问题标题】:setTimeout for v-alert after adding Item to an array basket将项目添加到数组篮后的 v-alert 的 setTimeout
【发布时间】:2020-08-17 12:53:37
【问题描述】:

这是我的rightTableMenu 模板

<template>
  <div>
    <h1 align="center">{{ title }}</h1>
    <v-alert type="info" icon="mdi-emoticon-sad" v-if="basketStatus">
      Empty Basket, please add some to basket
    </v-alert>
    <div v-if="changeAlertStatus()">
      <v-alert
        type="success"
        icon="mdi-emoticon-happy"
        :value="alert"
        transition="fade-transition"
      >
        thank you
      </v-alert>
      <v-simple-table>
        <template v-slot:default>
          <thead>
            <tr>
              <th class="text-left">Quantity</th>
              <th class="text-left">Name</th>
              <th class="text-left">Price</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="item in basket" :key="item.name">
              <td>
                <v-icon @click="increaseQuantity(item)">add_box</v-icon>
                <span>{{ item.quantity }}</span>
                <v-icon @click="decreaseQuantity(item)"
                  >indeterminate_check_box
                </v-icon>
              </td>
              <td>{{ item.name }}</td>
              <td>{{ (item.price * item.quantity).toFixed(2) }}</td>
            </tr>
          </tbody>
        </template>
      </v-simple-table>
      <v-divider color="black"></v-divider>
      <v-row id="basket_checkout" style="margin: 0">
        <v-col>
          <p>Subtotal:</p>
          <p>Delivery:</p>
          <p>Total amount:</p>
        </v-col>
        <v-col class="text-right">
          <p>${{ subTotalResult }}</p>
          <p>$10</p>
          <p class="font-weight-bold">${{ totalPriceResult }}</p>
        </v-col>
      </v-row>
      <v-row>
        <v-spacer></v-spacer>
        <v-btn depressed class="orange" v-on:click="submitOrder">
          <v-icon>shopping_basket</v-icon>
        </v-btn>
      </v-row>
    </div>
  </div>
</template>

如您所见,通过检查以下内容,当阵列篮内没有物品时,会显示两个警报

basketStatus() {
  return this.$store.getters.basket.length === 0;
},

这是计算属性 我的数据属性部分是

  data() {
    return {
      title: "Current Basket",
      alert: false,
    };
  },

但是对于第二个 v-alert,我想让警报在几秒钟后显示并消失,到目前为止我已经为它做了以下操作

  async changeAlertStatus() {
      if (this.$store.getters.basket.length !== 0) {
        this.alert = true;
        try {
          const response = await setTimeout(() => {
            this.alert = false;
          }, 100);
          console.log("this is the resonse " + response);
        } catch (err) {
          console.log("fetch failed", err);
        }
      } else {
        this.alert = false;
      }
    },

这是一种方法 我很困惑如何在不使用 v-if 指令的情况下插入 div 部分中的函数,并且当我在控制台中检查它并且 v-alert 不会消失时,我的 async changeAlertStatus 进入无限循环

对此有什么想法吗?

如果需要更多信息,请告诉我

谢谢你

以防我的leftTableMenu 被关注

<template>
  <div>
    <div v-if="showError['situation']">
    <!-- 
basically, when you close the alert, the value of the alert goes to false
so you need to turn it to true when there is an error  :value="showError.situation" -->
      <app-alert :text="showError.message"  :value.sync="showError.situation"></app-alert>
    </div>
    <h1 align="center">{{ title }}</h1>
    <v-simple-table od="menu-table">
      <template v-slot:default>
        <thead>
          <tr>
            <th class="text-left">Name</th>
            <th class="text-left">Price</th>
            <th class="text-left">Add</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="item in menuItems" :key="item.name">
            <td>
              <span id="id_name">{{ item.name }}</span>
              <br />
              <span id="menu_item_description">{{ item.description }}</span>
            </td>
            <td>{{ item.price }}</td>
            <td>
              <v-btn text v-on:click="addToBasket(item)">
                <v-icon color="orange">1add_shopping_cart</v-icon>
                <span></span>
              </v-btn>
            </td>
          </tr>
        </tbody>
      </template>
    </v-simple-table>
  </div>
</template>
<script>
export default {
  name: 'LeftTableMenu',
  data() {
    return {
      title: "Menu Items", 
    };
  },
  methods: {
    addToBasket(item) {
      this.$store.dispatch("addToBasket", item);
    },
  },
  computed: {
    showError() {
      return this.$store.getters.showError;
    },
    menuItems() {
      return this.$store.getters.menuItems;
    },
  },
};

【问题讨论】:

  • 不确定你为什么在v-if 中调用一个函数(?)changeAlerStatus(),如果它也没有返回任何东西。另外,你真的知道 setTimeout 是做什么的吗?为什么要等待它的回复?
  • @A. Lau 我是 vue js 的新手,除了使用 v-if 之外我不知道更好。是的 setTimeout 将任务放在线程的末尾,以便稍后运行。因为我希望它在几秒钟后消失,正如我所提到的。我完全同意 changeAlertStatus 不返回任何内容,但是如何在 div 中使用它来检查数组是否为空?
  • 您不需要等待 setTimeout,它不会返回承诺。 w3schools.com/jsref/met_win_settimeout.asp 另外,计算值不是函数,它们只是值,所以不需要调用它们。您的 changeAlertStatus() 应在 v-if 中更改为 alert。至少应该防止无限循环
  • 我怎样才能在几秒钟后消失?
  • 把你的 setTimeout 逻辑放到一个观察器中,观察basketStatusvuejs.org/v2/guide/computed.html#Watchers

标签: javascript vue.js vuetify.js settimeout


【解决方案1】:

你可以在你的计算属性上添加一个观察者来查看它是否被改变了。

当它发生变化时,您可以更新您的数据以显示或“成功”警报,然后设置超时以在一段时间后再次隐藏它。

为了清楚起见,这是一个更新的示例,其中更改了一些参数名称。

我将计算的名称更改为 emptyBasket

computed: {
  emptyBasket() {
    return this.$store.getters.basket.length === 0;
  }
},

我在数据中添加了 showSuccessAlert

data() {
  return {
    showSuccessAlert: false
  };
},

这里是更新 showSuccessAlert

的观察者
watch: {
  emptyBasket: {
    immediate: true,
    handler(newVal, oldVal) {
      this.showSuccessAlert = !newVal;
      setTimeout(() => {
        this.showSuccessAlert = oldVal;
      }, 5000);
    }
  }
}

观察者将立即被触发(不确定你是否需要它), newValoldVal 分别代表emptyBasket 的新旧状态。 所以当newValfalse时表示篮子不是空的,所以更新showSuccessAlert = !newVal

我用你的代码创建了一个简单的工作沙箱。

这里是链接:

https://codesandbox.io/s/smoosh-cherry-ngpqu?file=/src/App.vue

【讨论】:

  • inside watch 是做什么的?
  • 只有一个改变它对我有用,我否定了 setTimeout 中的值 oldVal
  • 我将 v-if=!basketStatus 放入外部 div 并将 v-if 放入 alert
【解决方案2】:

可能应该在看backStatus,然后做你的警报

watch: {
    // whenever question changes, this function will run
    backStatus: function (newVal, oldVal) {
        this.alert = newVal;
        const response = setTimeout(() => {
            this.alert = oldVal;
        }, 100); 
        // swap the vals around if needed
    }
}

也许你也需要立即,但这取决于你想要如何显示。

https://vuejs.org/v2/guide/computed.html#Watchers

【讨论】:

  • 这里以什么是newVal和oldVal为例?
  • 阅读文档。变量名也很容易解释。但在这个例子中,它将是真/假,因为这就是你的 backStatus 正在传递的内容
  • basketStatus 是计算属性,我无法将其添加到我的手表中,因为我搜索它不在要查看的数据属性中。那么对此有什么想法吗?
  • 很确定你可以。你有没有试过? stackoverflow.com/questions/41067378/…
  • 我会更新我的帖子,因为菜单由左右两个菜单组成
【解决方案3】:

与其在v-if 指令中调用changeAlertStatus,不如将​​其绑定到this.alert 属性?然后,当单击 Add to Cart 按钮时,其回调可以将 this.alert 设置为 true,从而显示警报。在将this.alert 设置为 true 后,注册 setTimeout 以将其恢复为 false

示例:(请原谅它的抽象性,我觉得这是原始帖子中缺少的代码,特别是添加到购物车按钮)

<template>
  <div id="app">
    <div class="alerts" v-if="alert">
      <div>Thank you</div>
    </div>
    <button @click="handleAddToCart">
      Add to cart
    </button>
  </div>
</template>

<script>
module.exports = {
  el: "#app",
  data: {
    alert: false,
    basketStatus: false
  },
  methods: {
    handleAddToCart() {
      this.alert = true;
      setTimeout(() => {
        this.alert = false;
      }, 3000);
    }
  }
};
</script>

【讨论】:

  • 你能给我一个样本或详细说明你的答案吗?
  • @KickButtowski 我已经用一个基本的代码示例更新了我的回复,希望对您有所帮助
  • 你能加入聊天吗?
  • 我不知道有聊天!我在哪里可以找到那个?
【解决方案4】:

您可以像其他人所说的那样使用手表来实现警报超时:

<template>
  <div class="w-full">

    <div class="w-full" v-for="item in cart" :key="item.id">
      <p>{{item.name}}</p>
    </div>

    <div class="w-full p-2 bg-yellow" v-if="alert">
      <p>Your cart is empty</p>
    </div>
  </div>
</template>

<script>
import axios from 'axios'
export default {
  name: 'CartList',
  data() {
    return {
      cart: [],
      alert: true
    }
  },
  watch: {
    cart(val) {
      if(!val.length) {
        this.alert = true
      } else {
        setTimeout(() => {
         this.alert = false
        }, 2000)
      }

    }
  },
  mounted() {
    this.getCart()
  },
  methods: {
    getCart() {
      axios('/cart/get').then((response) => {
        this.cart = response.data.cart
      })
    }
  }
}
</script>

但是您可以在请求函数中添加一些额外的代码并在那里添加超时:

getCart() {
  axios('/cart/get')
  .then((response) {
    if(response.data.cart.length) {
      setTimeout( () => { 
        this.alert = false
      }, 2000)
    }
  })
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-03
    • 1970-01-01
    • 1970-01-01
    • 2016-07-15
    相关资源
    最近更新 更多