将 Item 添加到数组篮子后的 v-alert 的 setTimeout

setTimeout for v-alert after adding Item to an array basket

这是我的 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></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 部分插入函数,当我在控制台中检查它时我的异步 changeAlertStatus 进入无限循环并且 v-alert 没有消失

有什么想法吗?

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

谢谢

以防万一我的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 指令中调用 changeAlertStatus,是否可以将其绑定到 this.alert 属性?然后,当单击“添加到购物车”按钮时,其回调可以将 this.alert 设置为 true,从而显示警报。在将 this.alert 设置为 true 之后,注册 setTimeout 以将其恢复为 false

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

<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>

可能应该正在观看 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
    }
}

也许您可能也需要 immediate,但这取决于您希望如何显示内容。

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

您可以在您的计算 属性 上添加观察者以查看它是否已更改。

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

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

我将计算名称更改为 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

的更新

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

这里是link:

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

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

<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)
    }
  })
}