VueJS - Is there a way to conditionally apply a transition?

Viewed 3624

What I would like to do is create an alert box component with a custom reveal transition that is optional, something like this (edited for brevity):

<template>
    <transition v-if="withTransition">
        <b-alert v-bind="this.$attrs" />
    </transition>
</template>

I will have a withTransition prop that ideally will conditionally render only the transition effect, and not affect the rendering of the alert box.

v-if and v-show won't work because those properties would show and hide the alert component as well. Plus, AFAIK <transition> does not render as a DOM element, so I'm not sure how that could be conditionally rendered, if at all.

Any suggestions?

2 Answers

You can use dynamic transitions and bind to a transition name (using a computed property) that does nothing when you want the effect disabled.

For example...

new Vue({
  el: '#app',
  data: () => ({ withTransition: true, show: false }),
  computed: {
    computedTransition () {
      return this.withTransition && 'fade'
    }
  }
})
.alert {
  background-color: #f99;
  border: 1px solid #f66;
  padding: 1rem;
}

.fade-enter-active, .fade-leave-active {
  transition: opacity .5s;
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
  opacity: 0;
}
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>

<div id="app">
  <p>
    <label>
      With transition:
      <input type="checkbox" v-model="withTransition"/>
    </label>
  </p>
  <p><button type="button" @click="show = !show">Toggle alert</button></p>
  <transition :name="computedTransition">
    <p class="alert" v-if="show">Something happened</p>
  </transition>
</div>

Use an inline ternary condition

If you just need to quickly check against a variable, this is an option:

<transition :name="someVariable == 'someValue' ? 'myTransitionA' : 'myTransitionB'">

someVariable could be anything (prop, data, computed, method...).

Set a transition name (e.g.'myTransitionB') to just an empty string '' if you wanted no transition at all for a particular condition.

I use this technique to toggle transitions based on different UI contexts (e.g. mobile vs desktop). For example, I want control bars to slide in-and-out in mobile, but I want them to be static on desktop.

Related