Energetic flair for Vue animations

I am currently developing a VueJS sidebar component. The objective is to allow the parent to define a width and display a toggle button that smoothly slides the sidebar in and out. Here is an example:

<template>
  <div class="sidebarContainer">
    <transition
        name="slide"
    >
      <div v-if="isOpen" class="sidebar" :style="{ width }">
        <slot/>
      </div>
    </transition>
    <div class="toggle" @click="isOpen = !isOpen">&lt;&gt;</div>
  </div>
</template>
export default {
  props: {
    'width': {
      default: '20em',
    }
  },
  data() {
    return {
      isOpen: true,
    };
  },
};
<style scoped>
.slide-enter-active, .slide-leave-active {
  transition: all 0.6s;
}
.slide-enter, .slide-leave-to {
  margin-left: -20em;
}
</style>

Check out this codepen. It functions as intended, with one caveat – the transition width (specified in the .slide-enter, .slide-leave-to style) is fixed and does not adjust based on the component's width property. This causes jitteriness if you set width=30em.

I have a hunch that I need to utilize transition hooks, but my attempts thus far have been unsuccessful. I experimented with the following:

beforeEnter(el) {
  el.style = {
    transition: 'all 0.6s',
    marginLeft: '-20em',
  };
},
enter(el, done) {
  el.style.marginLeft = '0';
  done();
},
beforeLeave(el) {
  el.style = {
    transition: 'all 0.6s',
    marginLeft: '0',
  };
},
leave(el, done) {
  el.style.marginLeft = '-20em';
  done();
},

Visit this modified codepen. Although the sidebar transitions, it does so instantaneously without animation. I even tried wrapping the done callback in setTimeout to allow the transition to complete, but it had no effect.

While I could resort to using libraries like Velocity or manually coding the animation, my intuition tells me there should be a simple way to let CSS handle it efficiently. What might I be overlooking?

Answer №1

Initially, the method you used to set the style did not work properly

el.style = {
   transition: 'all 0.6s',
   marginLeft: '-20em',
};

I have adjusted the style by moving transition: 'all 0.6s' to the CSS and setting the style like this

el.style.marginLeft = '-20em';

Secondly, the enter event was being called too soon after the beforeEnter event, causing the browser to not detect the change between the two states. To address this issue, I wrapped the enter event in a setTimeout function to trigger the transition effectively.

Lastly, the done callback is unnecessary in this scenario since we are using a combination of CSS and JavaScript for transitions.

Vue.component('app', {
  template: `<div class="app">
    <sidebar>sidebar content</sidebar>
    <div class="main">Hello, VueJS!</div>
  </div>`
});

Vue.component('sidebar', {
  template: `  <div class="sidebarContainer">
    <transition
        name="slide"
        @before-enter="beforeEnter"
        @enter="enter"
        @leave="leave"
    >
      <div v-if="isOpen" class="sidebar" :style="{ width }">
        <slot/>
      </div>
    </transition>
    <div class="toggle" @click="isOpen = !isOpen">&lt;&gt;</div>
  </div>`,
  props: {
    'width': {
      default: '20em',
    }
  },
  data() {
    return {
      isOpen: true,
    };
  },
  methods: {
    beforeEnter(el) {
      el.style.marginLeft = '-20em';
    },
    enter(el, done) {
      // Adding a brief delay here to ensure smooth transition
      setTimeout(() => {
        el.style.marginLeft = '0';
      }, 0)
    },
    leave(el, done) {
      el.style.marginLeft = '-20em';
    },
  },
});

new Vue({
  el: '#app',
  template: '<app/>'
});
html,
body,
.app {
  height: 100%;
}

.app {
  display: flex;
}

.main {
  flex-grow: 1;
  background: red;
}

.sidebarContainer {
  display: flex;
}

.sidebar {
  flex-grow: 1;
  padding: 0.5em;
  background: blue;
  transition: all 0.6s;
}

.toggle {
  margin: 0.5em;
}
<div id="app"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.min.js"></script>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

A guide on how to automatically preselect a RadioGroup option in Material-UI

When a user selects an option from the MCQ Select using RadioGroup in my code and submits it, they should be able to return later and see the option they selected highlighted, similar to how Google Forms allows users to review their selections. Below is t ...

Tips for bringing in an npm package in JavaScript stimulus

Looking to utilize the imageToZ64() function within the zpl-image module. After installing it with: npm install zpl-image I attempted importing it using: import './../../../node_modules/zpl-image'; However, when trying to use the function like ...

Arranging icons at the bottom of the post with a text box that changes dynamically

My challenge is that when the content in a box overflows, the box size increases and pushes the icons out of place. I want to ensure that the icons remain in a fixed position. This is how it currently looks: The comment, delete, and likes count end up on ...

What is the method for adding pages to the ion-nav component in Ionic with Angular?

How can I implement a UINavigationController-like functionality in iOS using an ion-nav element? The example provided here is in Javascript, but I need assistance with implementing it in Angular. Specifically, I'm unsure of how to programmatically add ...

NodeJs: Dealing with package vulnerabilities stemming from dependent npm packages - Tips for resolving the issue

Is there a way to address npm vulnerabilities that are dependent on another package? For instance, I'm encountering an error where the undici package relies on the prismix package. Things I have attempted: Executed npm audit fix Ensured Prismix is u ...

Error: The reduce function cannot be applied to $scope.array as it is not a

I am currently facing an issue with a section of my code that involves loading attributes related to a page using drop-down lists. These attributes, namely instruments, style, and scoring, are fetched through a service call. For instance, when retrieving ...

IE8 - Unable to use rgba()

I'm currently facing an issue with RGBA() manipulation in jQuery while using IE 8. Here's the code I have so far: $('.set').click(function (e) { var hiddenSection = $('div.hidden'); hiddenSection.fadeIn() . ...

Is there more to AJAX than just fetching a JSON file?

I am in need of using AJAX to achieve my goal. My aim is to have the content of specific subpages displayed in the HTML markup below when a particular link in a list is clicked. This data can be readily accessed from the database via the CMS's API (I ...

What is the best way to add a custom class alongside cdk-overlay-pane for a material menu in Angular 7?

I have a specific requirement to create a mega menu using Angular Material Menu. I attempted to apply some custom styling to the cdk-overlay-pane using my own class, but it did not work as expected. I tried to add a custom class to the mat-menu element us ...

An error of '______ is not defined' was thrown, I'm puzzled as to why

I keep encountering an error that says "weekday is not defined". I'm unsure of the reason behind this issue. Any assistance would be greatly appreciated! (function(exports) { var days = ["monday", "tuesday", "wednesday", "thursday"]; exports. ...

How to Insert PHP/MySql Data into JavaScript

As I delve deeper into PHP OOP, I feel like I'm making progress in transitioning my website. Currently, each user has their own page with a javascript grid tailored to their specific needs. For easier maintenance, I'm considering the idea of havi ...

Problem encountered when transferring JSON data to PHP for file writing

After spending numerous hours researching potential solutions, I still can't seem to fix the issue at hand. Admittedly, I am fairly new to PHP, so it's possible that I am overlooking a small detail. The problem lies in the fact that I have a form ...

Transmitting intricate Javascript Array to ASP.NET Controller Function

I am facing an issue with sending a complex JavaScript array to my asp.net mvc6 controller method. I have tried two different methods to pass the data, but neither seem to be working for me. public IActionResult TakeComplexArray(IList<ComplexArrayInfo ...

What is the best way to utilize this resulting value as an input?

I am trying to generate a random number using math.random and use that value in the following script: let bday = Math.floor( Math.random() * (30 - 1 + 1) + 1 ); await test.page.select('select[name="day_select"]',bday); However, I am ...

Automatically updating the results section while executing SQL queries in PHP

Here is a JavaScript/Ajax code snippet: <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js" type="text/javascript"></script> <script type="text/javascript"> $(document).ready (function () { var updater = se ...

Press `Enter` to confirm your selection in the BootstrapVue message box input box

Using Vue version v2.6.12 BootstrapVue version v2.21.2 Is there a way to confirm by pressing Enter instead of manually clicking OK? let text this.$bvModal.msgBoxConfirm(<input vModel={text} />) ...

Is it possible for Jquery to directly retrieve the form input without the need for a SET button in the script?

I have a script that functions as a basic countdown. All you need to do is enter a number, press the SET button, and click START for the countdown to begin. Although I primarily use this script in the gym, I often forget to hit the SET button after enteri ...

using a tag in flex can disrupt the arrangement of the box's design

What could be the reason for this issue? Is it possible to make the hyperlink appear inline with the rest of the text? .test { padding: 25px; display: flex; height: 100%; text-align: center; font-size: 25px; font-weight: 600; ...

What is the best way to eliminate all styles from an element with jQuery?

body{ font-family: Arial; } div{ color: red; margin: 20px; background: blue; font-size: 17px; } <div id="div1">this should be styled with a blue background, red text, and 17px Arial font</div> <div id ...

Inaccurate data saved to a cookie

I attempted to assign a string from PHP to a cookie and retrieve the value of that cookie using JavaScript. Take a look at my code snippet: <php $date=date('Y',time()); //assume it is 2017 setcookie("Year", $date, time() + 3600, "/"); ?> ...