setTimeout для v-alert после добавления Item в корзину массива - PullRequest
1 голос
/ 03 мая 2020

это мой 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 я хочу, чтобы предупреждение отображалось и исчезало через несколько се c, и пока я это сделал следующее для него

  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;
      }
    },

, который является методом, который я запутался, как вставить функцию в часть div без использования директивы v-if и мой asyn c changeAlertStatus получает бесконечный l oop когда я проверяю его внутри консоли и v-alert не исчезает

enter image description here

есть какие-нибудь мысли по этому поводу?

если потребуется дополнительная информация, пожалуйста, дайте мне знать

спасибо

на всякий случай, если мой 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;
    },
  },
};

Ответы [ 4 ]

1 голос
/ 03 мая 2020

Вероятно, вы должны смотреть 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

1 голос
/ 03 мая 2020

Вы можете добавить наблюдателя к вашему вычисленному свойству, чтобы увидеть, изменилось ли оно.

Когда оно изменится, вы можете обновить свои данные, чтобы показать или предупреждение «Успех», а затем установить тайм-аут, чтобы снова его скрыть. через некоторое время.

Вот обновленный пример с некоторыми измененными именами параметров для ясности.

Я изменил вычисленное имя на 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);
    }
  }
}

Наблюдатель будет срабатывает немедленно (не уверен, что вам это нужно), newVal и oldVal представляют новое и старое состояние emptyBasket. Поэтому, когда newVal равно false, это означает, что корзина не пуста, поэтому обновление showSuccessAlert = !newVal

Я создал простую рабочую песочницу с вашим кодом.

Вот ссылка:

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

0 голосов
/ 05 мая 2020

Вы можете добиться этого тайм-аута в режиме оповещения, используя часы, как говорили другие парни:

<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)
    }
  })
}
0 голосов
/ 03 мая 2020

Вместо того, чтобы вызывать changeAlertStatus в директиве v-if, это может быть просто связано со свойством this.alert? Затем, когда нажата кнопка «Добавить в корзину», ее обратный вызов может установить значение 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>
...