Answer a question

How to create an Alert in Vuetify that fade after specified number of seconds, similarly to the alerts in Bootstrap Vue. I tried this:

<template>
  <transition name="fade">
    <v-alert v-show="visible" v-bind="$attrs" v-on="$listeners">
      <slot></slot>
    </v-alert>
  </transition>
</template>

<script>
export default {
  inheritAttrs: true,
  data() {
    return {
      visible: true,
      timer: null
    };
  },
  props: {
    duration: {
      required: true,
      type: Number
    }
  },
  methods: {
    fade() {
      let value = parseInt(Math.max(this.duration, 0));
      if (value != 0)
        this.timer = setTimeout(() => (this.visible = false), 1000 * value);
    }
  },
  mounted() {
    this.fade();
  }
};
</script>

Usage in other components:

    <vt-alert
      v-if="hasMessage()"
      :type="message.type"
      :duration="message.duration"
    >{{message.body}}</vt-alert>

hasMessage is utility function which check if the message is set.

But this did not work. More details here,

Answers

No need for so much code and custom ideas :) Use vuetify API (Less code = easier to maintain):

https://vuetifyjs.com/en/components/alerts/#api

A. Show/Hide

The alert get value (false => hide. True => show).

<v-alert :value="alert">
data () {
  return {
   alert: false,
}

Toggle alert to true/false on click, hover, timer or any logic you want.

Docs toogle example: https://vuetifyjs.com/en/components/alerts/#transition

B. transition props

Use any build-in transition you want. List her: https://vuetifyjs.com/en/styles/transitions/#motion

<v-alert transition="fade-transition">

A+B: Basic "hello world" example

On click show alert & slide-y-transition out after 3 seconds.

new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data () {
    return {
      alert: false,
    }
  },
  // define methods under the `methods` object
  methods: {
    hide_alert: function (event) {
      console.log('Hide')
      // `event` is the native DOM event
      window.setInterval(() => {
        this.alert = false;
        console.log("hide alert after 3 seconds");
      }, 3000)    
    }
  },
  mounted: function () {
    if(alert){
      this.hide_alert();
    }
  }
})
<link href="https://cdn.jsdelivr.net/npm/vuetify@2.2.18/dist/vuetify.min.css" rel="stylesheet"/>
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@4.x/css/materialdesignicons.min.css" rel="stylesheet"/>

<div id="app">
  <v-app id="inspire">
    <div>
      <div class="text-center mb-4">
        <v-btn
               color="primary"
               @click="alert = true"
               >
          Show alert? {{alert}}
        </v-btn>
      </div>
      <v-alert
               :value="alert"
               color="pink"
               dark
               border="top"
               icon="mdi-home"
               transition="slide-y-transition"
               >
        Phasellus tempus. Fusce ac felis sit amet ligula pharetra condimentum. In dui magna, posuere eget, vestibulum et, tempor auctor, justo. Pellentesque posuere. Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo.

        Phasellus nec sem in justo pellentesque facilisis. Phasellus magna. Cras risus ipsum, faucibus ut, ullamcorper id, varius ac, leo. In hac habitasse platea dictumst. Praesent turpis.
      </v-alert>
    </div>
  </v-app>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@2.2.18/dist/vuetify.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/babel-polyfill/dist/polyfill.min.js"></script>

Extra features example

Show timer (3..2..1) when the alert visible + toggle the alert on a button click.

About dismissible the best idea is to create a custom X button (And use the same show/hide function) ***Until the API gives more options related to this feature (Styling/position and so on).

new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data () {
    return {
      message: "show alert? - ",
      alert: false,
      countDown: {
        timer: "3",
        show: false
      },
    }
  },
  // define methods under the `methods` object
  methods: {
    show_alert_and_fade: function(){
      /* toogle alert on click */
      this.alert = !this.alert; 
      /* hide alert after 3 seconds */
      this.resetTimer();
      this.countDownTimer();
      /*  If alert visible - setTimeout() => only executed once */
      if(this.alert == true){
        myTimer = window.setTimeout(() => {
          this.alert = false;
          console.log("Case 1: Time ends - hide alert");
        }, 3000);
      }else{
        /* If alert hidden - clear setTimeout */
        console.log("Case 2: User Hide alert by click - stop setTimeout");
        clearTimeout(myTimer);
        this.resetTimer();
      }
    },
    dismissible_close (value) {
      this.alert = value;
      this.resetTimer();
    },
    /*  recursion function - run time if remain time and alert if visible */ 
    countDownTimer() {
      if(this.countDown.timer > 0 && this.alert) {
        this.countDown.show = true;
        var myTimer = setTimeout(() => {
          this.countDown.timer -= 1;
          this.countDownTimer();
        }, 1000)
        }
      else{
        /* do something */
        this.resetTimer();
      }
    },
    resetTimer(){
      this.countDown.timer = 3;    
    },
    hideTimer(){
      this.countDown.show = false; 
    }
  }
})
body{
  padding: 10px;
}

#close_btn{
  position: absolute;
  right: 6px;
  top: 12px;
}
<link href="https://cdn.jsdelivr.net/npm/vuetify@2.2.18/dist/vuetify.min.css" rel="stylesheet"/>
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@4.x/css/materialdesignicons.min.css" rel="stylesheet"/>

<div id="app">
  <v-app id="inspire">
    <div>
      <div class="text-center mb-4">

        <!-- remove countDown for demo only -->

        <v-btn
               v-bind:color="alert ? 'success' : 'error'"
               @click="show_alert_and_fade"
               v-bind:class="{ active: alert }"
               >
          {{message}} <b> {{alert}}</b>

        </v-btn>

        <v-badge v-if="alert"
                 :content="countDown.timer"
                 :value="countDown.timer"
                 color="red"
                 overlap
                 >
        </v-badge>
      </div>
      <v-alert
               :value="alert"
               color="success"
               dark
               border="top"
               icon="mdi-home"
               transition="slide-y-transition"
               @input="dismissible_close"
               >
        <div id="close_btn">
          <v-btn  color="success" fab x-small @click="show_alert_and_fade">
            <v-icon>mdi-close</v-icon>
          </v-btn>
        </div>

        <div class="pt-6 pr-6">
          <p>
            Phasellus tempus. Fusce ac felis sit amet ligula pharetra condimentum. In dui magna, posuere eget, vestibulum et, tempor auctor, justo. Pellentesque posuere. Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo.
          </p>
          <p>
            Phasellus nec sem in justo pellentesque facilisis. Phasellus magna. Cras risus ipsum, faucibus ut, ullamcorper id, varius ac, leo. In hac habitasse platea dictumst. Praesent turpis.
          </p>

        </div>
      </v-alert>
    </div>
  </v-app>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@2.2.18/dist/vuetify.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/babel-polyfill/dist/polyfill.min.js"></script>
Logo

Vue社区为您提供最前沿的新闻资讯和知识内容

更多推荐